如果没有对象创建,变量 int a 是如何存在的?它也不是静态类型。
#include <iostream>
using namespace std;
class Data
{
public:
int a;
void print() { cout << "a is " << a << endl; }
};
int main()
{
Data *cp;
int Data::*ptr = &Data::a;
cp->*ptr = 5;
cp->print();
}
答案 0 :(得分:2)
您的代码显示了一些未定义的行为,让我们来看看它:
在堆栈上创建一个指针,但不会初始化它。虽然它本身不是问题,但它应该在某个时候初始化。现在,它可以包含0x0badc0de
用于我们所知道的所有内容。
没有错,它只是创建一个指向成员的指针。
非常危险的代码,您现在正在使用cp
而不进行初始化。在最好的情况下,这会使您的程序崩溃。您现在将5
分配给cp
指向的内存。由于这没有初始化,你正在写入内存空间的某个地方。这可以包括最好的情况:你不拥有的内存,没有写访问权限的内存。在这两种情况下,您的程序都可能崩溃。在最坏的情况下,这实际上会写入您拥有的内存,从而导致数据损坏。
不那么危险,仍未定义,所以会读取内存。如果您达到此声明,则内存很可能会分配给您的程序,并且会打印5
。
这个程序实际上可能正常工作,你可能能够执行它,因为你的编译器对它进行了优化。它注意到你写了一个写,然后是一个读,之后忽略了内存。因此,它实际上可以优化您的程序:cout << "a is "<< 5 <<endl;
,这是完全定义的。
因此,如果出于某些未知原因,这实际上是有效的,那么您的程序中就会出现错误,该错误会导致程序损坏或崩溃。
请改为写下以下内容:
int main()
{
int stackStorage = 0;
Data *cp = &stackStorage;
int Data::*ptr=&Data::a;
cp->*ptr=5;
cp->print();
}
答案 1 :(得分:0)
我想在此示例中使用的类型中添加更多内容。
int Data::*ptr=&Data::a;
对我来说,ptr是指向Data的int成员的指针。 Data::a
不是实例,因此地址运算符返回a
中Data
的偏移量,通常为0.
cp->*ptr=5;
这解除引用cp,一个指向Data的指针,并应用存储在ptr中的偏移量,即0,即a;
所以两行
int Data::*ptr=&Data::a;
cp->*ptr=5;
只是一种混淆的写作方式
cp->a = 5;