我试图在不使用对象的情况下访问类的成员变量.请让我知道如何去做.
class TestMem
{
int a;
int b;
public:
TestMem(){}
void TestMem1()
{
a = 10;
b = 20;
}
};
void (TestMem::*pMem)();
int main(int argc, char* argv[])
{
TestMem o1;
pMem = &(TestMem::TestMem1);
void *p = (void*)&pMem;
// How to access a & b member variables using variable p
getch();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
执行此操作的"正确"方法是使用offsetof()
宏来自<stddef.h>
.不幸的是,在C++中offsetof()
有一些相当严苛的限制:
由于C++中结构体的扩展功能,在这种语言中,使用
offsetof
限制为"POD [普通旧数据]类型",对于类,或多或少对应于结构的C概念(尽管非派生类)只有公共非虚拟成员函数,没有构造函数和/或析构函数也有资格作为POD).
因此,如果你制作a
并b
公开并摆脱TestMem
构造函数,你可以写这样的东西来访问a
:
#include <cstddef>
int vala = *reinterpret_cast<int *>(reinterpret_cast<char *>(&o1)
+ offsetof(TestMem, a));
Run Code Online (Sandbox Code Playgroud)
#include <stddef.h>
int vala = *(int *) ((char *) &o1 + offsetof(TestMem, a));
Run Code Online (Sandbox Code Playgroud)
请注意,您需要在此使用&o1
,而不是p
函数指针.地址TestMem::TestMem1
不会有任何关系的位置a
和b
.类方法不驻留在类成员变量附近的内存中.
"错误"的方式是猜测内存a
和b
内存.最有可能的是,它们分别位于开始时的偏移0和4 o1
.所以这段代码大部分时间都可以工作:
int vala = *(int *) ((char *) &o1 + 0);
int valb = *(int *) ((char *) &o1 + 4);
Run Code Online (Sandbox Code Playgroud)
这里有很多假设.这是假定int为4个字节,并且有之间没有填充a
和b
.另一方面,它没有上面的任何限制:a
并且b
不需要公开,你可以有一个构造函数,无论如何.