2

我有一个包含一些数据成员的自定义类。我有一个指向该类的数据成员之一的指针,我想要一个指向其封闭实例的指针。例如:

class MyClass{
public:
    int a;
    int b;
    virtual ~MyClass(){//because MyClass is not POD type
    }
};

...

int* aptr = ...; //something valid, and i know its a pointer to a MyClass::a member
MyClass* classptr = ?; //how can i get a pointer to the class instance?

该类不是 POD 类型,因此 offsetof 宏并不总是有效/它会给出编译警告。

是否可以获得指向 MyClass 实例的指针?

4

3 回答 3

4

您不能使用定义明确的 C++ 来执行此操作,因为不相关类型之间的强制转换是未定义的行为。

实际上,您可能会假设一个类的第一个成员的地址与该类的地址相同,该地址是系统上指针大小的偏移量。(这个指针是 v-table 的实现,并且在 C++ 实现中相当一致。)然后,如果您对数据成员的打包做出一些假设,那么您可以手动调整指针以从一个数据成员移动到其他。offsetof是另一种技术,可以在这里为您提供帮助,但在您的上下文中仍未明确定义。

要么用特定的编译器断言乱扔你的源代码(因为你正在限制可移植性),要么采用不同的技术。我当然会采用后者。

这是一些非常糟糕的代码,它向您展示了如何做到这一点。考虑

struct Foo
{
    virtual ~Foo(){}; /*introduce a v-table*/
    int n;
};

和,

  Foo foo;
  foo.n = 0xdeadbeef; // To test
  int* p = &foo.n; // Suppose this is our pointer.
  char* pp = (char*)(void*)p; // This cast is undefined behaviour.
  pp -= 8; // Skip over 64 bit v-table. More undefined behaviour.
  Foo* ph = (Foo*)(pp); // Yet more undefined behaviour.

ph指向一个Foo实例。

于 2015-08-12T09:39:53.790 回答
1

CONTAINING_RECORD是可能对您有用的宏,它经常与链表一起使用,其中指向下一个和上一个项目的指针嵌入在另一个结构中。

于 2015-08-12T09:49:15.023 回答
1

不,这在标准 C++ 中是不可能的。offsetof是做这种事情的唯一可移植方式,它只适用于标准布局类。如果它不起作用(或者您无法抑制并忽略警告),那么您就不走运了。

于 2015-08-12T09:37:26.047 回答