多变的' a'将在没有任何对象创建的情况下存在?

时间:2017-04-26 10:26:41

标签: c++ class pointers

如果没有对象创建,变量 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();
}

2 个答案:

答案 0 :(得分:2)

您的代码显示了一些未定义的行为,让我们来看看它:

数据* cp;

在堆栈上创建一个指针,但不会初始化它。虽然它本身不是问题,但它应该在某个时候初始化。现在,它可以包含0x0badc0de用于我们所知道的所有内容。

int Data :: * ptr =&amp; Data :: a;

没有错,它只是创建一个指向成员的指针。

CP-&GT * PTR = 5;

非常危险的代码,您现在正在使用cp而不进行初始化。在最好的情况下,这会使您的程序崩溃。您现在将5分配给cp指向的内存。由于这没有初始化,你正在写入内存空间的某个地方。这可以包括最好的情况:你不拥有的内存,没有写访问权限的内存。在这两种情况下,您的程序都可能崩溃。在最坏的情况下,这实际上会写入您拥有的内存,从而导致数据损坏。

CP-&GT;打印();

不那么危险,仍未定义,所以会读取内存。如果您达到此声明,则内存很可能会分配给您的程序,并且会打印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不是实例,因此地址运算符返回aData的偏移量,通常为0.

cp->*ptr=5;

这解除引用cp,一个指向Data的指针,并应用存储在ptr中的偏移量,即0,即a;

所以两行

int Data::*ptr=&Data::a;
cp->*ptr=5;

只是一种混淆的写作方式

cp->a = 5;