我可以使用C ++中的[]运算符来创建虚拟数组 [英] Can I use the [] operator in C++ to create virtual arrays

查看:284
本文介绍了我可以使用C ++中的[]运算符来创建虚拟数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个大的代码库,原来C移植到C ++多年前,这是操作在一些大型空间数据数组。这些数组包含表示表示表面模型的点和三角形实体的结构。我需要重构代码,使这些实体存储在内部的具体方式因具体情况而异。例如,如果点位于规则的平面网格上,我不需要存储X和Y坐标,因为它们可以在飞行中计算,三角形也是如此。同样,我希望利用诸如 STXXL 等核心工具进行存储。最简单的方法是用put和get类型函数替换数组访问,例如

I have a large code base, originally C ported to C++ many years ago, that is operating on a number of large arrays of spatial data. These arrays contain structs representing point and triangle entities that represent surface models. I need to refactor the code such that the specific way these entities are stored internally varies for specific scenarios. For example if the points lie on a regular flat grid, I don't need to store the X and Y coordinates, as they can be calculated on the fly, as can the triangles. Similarly, I want to take advantage of out of core tools such as STXXL for storage. The simplest way of doing this is replacing array access with put and get type functions, e.g.

point[i].x = XV;

成为

Point p = GetPoint(i);
p.x = XV;
PutPoint(i,p);

你可以想象,这是一个非常乏味的重构器在一个大的代码库,的错误。我想做的是编写一个类,通过重载[]运算符模仿数组。因为数组已经存在于堆上,并且随着realloc一起移动,代码已经假定对数组的引用,例如

As you can imagine, this is a very tedious refactor on a large code base, prone to all sorts of errors en route. What I'd like to do is write a class that mimics the array by overloading the [] operator. As the arrays already live on the heap, and move around with reallocs, the code already assumes that references into the array such as

point *p = point + i;

不能使用。这个类可写吗?例如,使用[]运算符编写以下方法:

may not be used. Is this class feasible to write? For example writing the methods below in terms of the [] operator;

void MyClass::PutPoint(int Index, Point p)
{
   if (m_StorageStrategy == RegularGrid)
   {
      int xoffs,yoffs;
      ComputeGridFromIndex(Index,xoffs,yoffs);
      StoreGridPoint(xoffs,yoffs,p.z);
    } else
       m_PointArray[Index] = p;   
  }
}

Point MyClass::GetPoint(int Index)
{
   if (m_StorageStrategy == RegularGrid)
   {
      int xoffs,yoffs;
      ComputeGridFromIndex(Index,xoffs,yoffs);
      return GetGridPoint(xoffs,yoffs);   // GetGridPoint returns Point
    } else
       return m_PointArray[Index];   
  }
}

我关心的是所有的数组类看到倾向于通过引用,而我认为我必须传递结构的值。我认为它应该工作除性能之外,任何人都可以看到任何重大陷阱与这种方法。 n.b.我必须通过值的原因是获取

My concern is that all the array classes I've seen tend to pass by reference, whereas I think I'll have to pass structs by value. I think it should work put other than performance, can anyone see any major pitfalls with this approach. n.b. the reason I have to pass by value is to get

point[a].z = point[b].z + point[c].z

可以正确运行底层存储类型。

to work correctly where the underlying storage type varies.

推荐答案

是最好的前进方向。为了在运行时处理类型之间的变形,我创建了一个新的数组模板类,它采用如下四个参数:

After reading the above answers, I decided that Pete's answer with two versions of operator[] was the best way forward. To handle the morphing between types at run-time I created a new array template class that took four parameters as follows;

template<class TYPE, class ARG_TYPE,class BASE_TYPE, class BASE_ARG_TYPE>
class CMorphArray 
{
int GetSize() { return m_BaseData.GetSize(); }
BOOL IsEmpty() { return m_BaseData.IsEmpty(); }

// Accessing elements
const TYPE& GetAt(int nIndex) const;
TYPE& GetAt(int nIndex);
void SetAt(int nIndex, ARG_TYPE newElement);
const TYPE& ElementAt(int nIndex) const;
TYPE& ElementAt(int nIndex);

// Potentially growing the array
int Add(ARG_TYPE newElement);

// overloaded operator helpers
const TYPE& operator[](int nIndex) const;
TYPE& operator[](int nIndex);

   CBigArray<BASE_TYPE, BASE_ARG_TYPE>  m_BaseData;
private:
   CBigArray<TYPE, ARG_TYPE>    m_RefCache;
   CBigArray<int, int&> m_RefIndex;
   CBigArray<int, int&> m_CacheIndex;

   virtual void Convert(BASE_TYPE,ARG_TYPE) = 0;
   virtual void Convert(TYPE,BASE_ARG_TYPE) = 0;

   void InitCache();
   TYPE&    GetCachedElement(int nIndex);
};

主数据存储位于 m_BaseData 是其原生格式的数据,其可以如所讨论的类型变化。 m_RefCache 是以预期格式缓存元素的辅助数组, GetCachedElement 函数使用虚拟转换函数以在数据移入和移出高速缓存时翻译数据。缓存需要至少与同时引用的同时引用的数量一样大,但在我的情况下,可能会受益于更大,因为它减少了所需的转换次数。虽然Alsk的游标实现可能工作得很好,给出的解决方案需要更少的对象副本和临时变量,并且应该提供略微更好的性能,这在这种情况下很重要。

The main data storage is in m_BaseData which is the data in its native format, which can vary in type as discussed. m_RefCache is secondary array to cache of elements in the expected format, and the GetCachedElement function uses the virtual Convert functions to translate the data as it is moved in and out of the cache. The cache needs to be at least as big as the number of simultaneous references that can be active at any one time, but in my case will probably benefit from being bigger as it reduces the number of conversions required. While Alsk's cursor implementation probably would have worked well, the solution given requires fewer object copies and temporary variables, and ought to afford slightly better performance which is important in this case.

向所有的STL粉丝表示歉意旧的MFC外观和感觉;该项目的其余部分是MFC,因此在这种情况下更有意义。 CBigArray是一个相关的栈溢出问题成为我的大阵列处理的基础。我希望今天完成实施,明天测试。如果一切都在我身上,我会编辑这篇文章。

Apologies to all you STL fans for the older MFC look and feel; the rest of the project is MFC so it makes more sense in this case. The CBigArray was the result of a related stack overflow question that became the basis of my large array handling. I hope to finish the implementation today and test tomorrow. If it all goes belly up on me, I'll edit this post accoringly.

这篇关于我可以使用C ++中的[]运算符来创建虚拟数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆