使用指针算法迭代C ++中的类数据成员

时间:2014-03-06 15:53:35

标签: c++ arrays class pointers

我有一个C ++类,包含一堆相同类型的数据成员,我想迭代它们:

// C.h

class C {

  // other members

  double foo;
  double bar;
  ...
  double barf; // 57th double declared since foo, nothing else in between

  // other members
};

指针算法似乎有用,例如这里使用构造函数初始化那58个成员的双打:

// C.cpp

C::C() {
  for (int i = 0; i < 58; i++) {
    *(&this->foo + i) = 0;
  }
}

我在How to iterate through variable members of a class C++C++: Iterating through all of an object's members?,此处Are class members garaunteed to be contiguous in memory?以及此处Class contiguous data找到了相关问题,有些人认为这种事情还可以,其他人则不没有。后者说不能保证它不会失败,但不要引用它实际上失败的任何实例。所以我的问题是,是否有其他人使用过这个,或者已经尝试过并遇到麻烦了?

或许还有更好的方法?最初在我的应用程序中,我实际上使用数组代替我的对象,索引如下:

int i_foo = 0, i_bar = 1, ..., i_barf = 57;

然而,一旦我引入了不同的对象(及其数组),索引命名开始失控。另外我想学习课程,我希望其他一些功能可以证明有用; - )

我非常重视迭代,例如计算对象集合的统计信息。当然,我可以创建一个函数来逐个将类成员映射到一个数组,但性能是一个优先事项。我正在为自己开发这个应用程序,以便在Windows上使用VS.我想保持其他平台选项开放,但这不是我打算广泛分发的东西。感谢

2 个答案:

答案 0 :(得分:3)

乔治:

我认为你可以有更好的解决方案(比如将返回第i个属性的方法:

double get(size_t idx)
{
  switch (idx)
  {
    case 0: return foo; 
    case 1: return bar;
    case 2: return foo_bar;
    ....
  }
}

答案 1 :(得分:0)

使用指针算法迭代类数据成员可能会在代码优化期间导致问题。例如:

struct Vec3
{
    double x, y, z;

    inline Vec3& operator =(const Vec3& that)
    {
        x = that.x;
        y = that.y;
        z = that.z;
        return *this;
    }

    inline double& operator [](int index)
    {
        return (&x)[index];
    }
};

...
Vec3 foo = bar;            // operator =
double result = foo[2];    // operator []
...

两个运算符都是内联的,结果的值取决于最终的指令重新排序。可能的情况:

foo.x = bar.x;
foo.y = bar.y;
foo.z = bar.z;
result = (&foo.x)[2];    // correct -- result contains new value

foo.x = bar.x;
foo.y = bar.y;
result = (&foo.x)[2];    // incorrect -- result contains old value
foo.z = bar.z;

foo.x = bar.x;
result = (&foo.x)[2];    // incorrect -- result contains old value
foo.y = bar.y;
foo.z = bar.z;

有些编译器没有意识到(&amp; foo.x)[2]与foo.z的数据相同,并且他们不正确地重新排序指令。很难找到这样的bug。