我正在寻找一种方法来获取具有非 POD 性质的 C++ 类的数据成员的偏移量。
原因如下:
我想以HDF5格式存储数据,这似乎最适合我的材料(数值模拟输出),但它可能是一个相当面向 C 的库。我想通过 C++ 接口使用它,这需要我像这样声明存储类型(遵循此处和此处的文档(第 4.3.2.1.1 节)):
class example {
public:
double member_a;
int member_b;
} //class example
H5::CompType func_that_creates_example_CompType() {
H5::CompType ct;
ct.insertMember("a", HOFFSET(example, member_a), H5::PredType::NATIVE_DOUBLE);
ct.insertMember("b", HOFFSET(example, member_b), H5::PredType::NATIVE_INT);
return ct;
} //func_that_creates_example_CompType
其中 HOFFSET 是一个使用 offsetof 的特定于 HDF 的宏。
问题当然是,一旦示例类变得更有特色,它就不再是 POD 类型的,因此使用 offsetof 将给出未定义的结果。
我能想到的唯一解决方法是首先将要存储的数据导出到更简单的结构,然后将其传递给 HDF。然而,这确实涉及数据复制,这正是 HDF 试图避免的(以及为什么他们有这个 CompType 使库能够访问您的对象以将其数据保存到文件)。
所以我希望你有更好的想法。理想情况下,我会为这个问题寻找一种可移植的解决方法,但如果没有的话,你可以给我一个可以在 x86 和 x86_64 上使用 GCC 的想法,我已经非常感激了。
----- 稍后附加: -----
Greg Hewgill 在下面建议将数据存储在一个简单的结构中,然后通过继承来构建实际的类。特别是对于 HDF,我认为这实际上可能行不通。比上面更复杂的使用场景:
class base_pod {
public:
double member_a;
int member_b;
}; //class base_pod
class derived_non_pod : private base_pod {
public:
//the following method is only virtual to illustrate the problem
virtual double get_member_a() {return member_a; }
}; //class derived_non_pod
class that_uses_derived_non_pod {
public:
void whatever();
private:
derived_non_pod member_c;
}; //class that_uses_derived_non_pod
现在,当我们存储 that_uses_derived_non_pod 类的实例时,我们无法描述它的内存布局,就好像它有一个 base_pod 作为 member_c。这会使偏移量出错,因为 derived_non_pod 添加了一些时髦的东西(我猜是虚拟函数表?)。