C++对象、成员的内存位置偏移

发布于 2024-08-10 06:28:52 字数 216 浏览 7 评论 0原文

有没有比下面更好的方法来建立对象数据成员的位置偏移量?

class object
{
  int a;
  char b;
  int c;
};

object * o = new object();
int offset = (unsigned char *)&(object->c) - (unsigned char *)o;
delete o;

Is there a better method to establish the positional offset of an object's data member than the following?

class object
{
  int a;
  char b;
  int c;
};

object * o = new object();
int offset = (unsigned char *)&(object->c) - (unsigned char *)o;
delete o;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

昇り龍 2024-08-17 06:28:52

在本例中,您的类是 POD,因此您可以使用 中的 offsetof 宏。

实际上,在大多数实现中,对于大多数类,您可以使用 offsetof 通常使用的相同技巧:

int offset = &(((object *)0)->c) - (object *)0;

不需要实际创建对象,尽管您可能必须克服一些编译器警告,因为这不能保证有效。

另请注意,如果您的类具有任何多重继承,则对于(至少)除一个基类之外的所有类,(void*)(base*)some_object != (void*)(衍生*)some_object。因此,您必须小心应用偏移量的内容。只要您相对于实际定义该字段的类的指针来计算和应用它(也就是说,不要尝试计算出基类字段与派生类指针的偏移量),您几乎肯定会美好的。无法保证对象布局,但大多数实现都以显而易见的方式进行。

从技术上讲,对于任何非 POD 类,谈论字段相对于基指针的“偏移量”是没有意义的。对于该类的所有对象,指针之间的差异不需要相同。

In this case, your class is POD, so you can use the offsetof macro from <cstddef>.

In practice, in most implementations, for most classes, you can use the same trick which offsetof typically uses:

int offset = &(((object *)0)->c) - (object *)0;

No need to actually create an object, although you may have to fight off some compiler warnings because this is not guaranteed to work.

Beware also that if your class has any multiple inheritance, then for (at least) all but one base, (void*)(base*)some_object != (void*)(derived*)some_object. So you have to be careful what you apply the offset to. As long as you calculate and apply it relative to a pointer to the class that actually defines the field (that is, don't try to work out the offset of a base class field from a derived class pointer) you'll almost certainly be fine. There are no guarantees about object layout, but most implementations do it the obvious way.

Technically for any non-POD class, it does not make sense to talk about "the offset" of a field from the base pointer. The difference between the pointers is not required to be the same for all objects of that class.

负佳期 2024-08-17 06:28:52

而不是指针。
您可以使用指向成员的指针。

class X;
typedef int X::*    PtrToMemberInt;  // Declare a pointer to member.

class X
{
    int a;
    char b;
    float c;

    public:
    static PtrToMemberInt   getAPtr()
    {
        return &X::a;
    }

    int d;
};

int main()
{
    // For private members you need to use a public method to get the address.
    PtrToMemberInt aPtr = X::getAPtr();

    // For public members you can take the address directly;
    PtrToMemberInt dPtr = &X::d;


    // Use the pointer like this:
    X   a;
    a.*aPtr = 5;
    a.*dPtr = 6;
}

Rather than a pointer.
You can use a pointer to a member.

class X;
typedef int X::*    PtrToMemberInt;  // Declare a pointer to member.

class X
{
    int a;
    char b;
    float c;

    public:
    static PtrToMemberInt   getAPtr()
    {
        return &X::a;
    }

    int d;
};

int main()
{
    // For private members you need to use a public method to get the address.
    PtrToMemberInt aPtr = X::getAPtr();

    // For public members you can take the address directly;
    PtrToMemberInt dPtr = &X::d;


    // Use the pointer like this:
    X   a;
    a.*aPtr = 5;
    a.*dPtr = 6;
}
情场扛把子 2024-08-17 06:28:52

要添加到 Martin 的答案,如 Stroustrup 的“C++ 的设计和演化”(第 [13.11] 节)中所述:

事实证明,指向数据成员的指针
表达布局的有用方法
实现中的 C++ 类
[许贝尔,1992]

Sandeep 非常友善地转换了原始论文并将其发布在 http://sandeep.files.wordpress.com/2008/07/ps.pdf

请注意,所描述的实现早于 C++ RTTI,但我偶尔仍然使用指向成员的指针。

To add to Martins answer, as stated in "Design and Evolution of C++" by Stroustrup (section [13.11]):

pointers to data members have proven a
useful way of expressing the layout of
a C++ class in an implementation
[Hübel, 1992]

Sandeep has been so kind as to convert the original paper and make it available on http://sandeep.files.wordpress.com/2008/07/ps.pdf

Note that the implementation described predated C++ RTTI, but I occasionally still use the pointer-to-member stuff.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文