是否可以手动计算类成员的字节偏移量?

时间:2011-07-13 16:41:42

标签: c++ compiler-construction class-members

也就是说,编译器用来生成类的标准是什么?例如,假设我有成员Cxy的课程z,我想知道其中z的偏移量类。我可以只添加其他成员的数据类型大小,就像我对结构一样吗?

7 个答案:

答案 0 :(得分:8)

不,你不能。
编译器可以根据用户的意愿自由调整成员。这是编译器的实现细节。

如果您使用 POD ,则可以使用 offsetof 宏。

但如果使用非POD ,那么我认为没有任何便携方法可以这样做。

答案 1 :(得分:4)

您可以在类的方法中以编程方式执行此操作。不通用但有效。

offset = (unsigned char*)&(this->z) - (unsigned char*)this;

完整的工作示例

#include <iostream>

class C
{
public:
    int x;
    char y;
    int z;
    size_t offset() const
    {
        return (unsigned char*)&(this->z) - (unsigned char*)this;
    }
};

int main()
{
    C c;
    std::cerr << "Offset(cast): " << c.offset() << "\n";
}

答案 2 :(得分:2)

您可以通过使用样本对象计算偏移来实现此目的。 (参见@ bert-jan或@ sodved的回答)。

然而,这是危险!您不能将c ++类和结构视为您想象的常规结构。

问题在于,对于任何给定的指向对象的指针,偏移量可能会有所不同!

为什么呢?由于子类化和多重继承,可以在之前将其他数据放在常规struct成员之前。数据量可能因您班级的每个不同子类而异。


有关详细信息,请参阅此问题:Why can't you use offsetof on non-POD structures in C++?

答案 3 :(得分:1)

您可以使用&(class_name::member_name)来获得抵消。

答案 4 :(得分:0)

答案 5 :(得分:0)

绝对不符合标准。但是,有一些特定于编译器的解决方案可以帮助您推断它。

微软有这个:

#pragma pack(push,1)
struct Foo {
  uint8 a;
  uint32 b;
};
#pragma pack(pop)

我可以传递(仅通过传闻)GCC也支持扩展。

答案 6 :(得分:-1)

    #define _OFFSET(p_type, p_member) (size_t)(&((p_type *)NULL)->p_member)

    struct a
   {
       int a, b;
   };

   cout << _OFFSET(struct a, b); // output is your offset