#include <iostream>
using namespace std;
class A
{
private:
int m_i;
friend int main(int argc, char const *argv[]);
public:
A (int i = 0):m_i(i){};
void display()
{
cout << m_i << endl;
}
int result() {return m_i;}
};
void createA(A *pa)
{
pa = new A(1);
}
A* createA()
{
A a(2);
return &a;
}
void createAonstack()
{
A a(3);
}
int main(int argc, char const *argv[])
{
A a;
A * pa = &a;
pa->display();
createA(pa);
pa->display();
A * a2 = createA();
cout << a2->m_i << endl;
createAonstack();
cout << a2->m_i << endl;
return 0;
}
上述程序的结果是
0
0
2
3
如何解释结果2和3?根据我的理解,函数createA()
中创建的对象应该被解构,它返回的指针应该指向NULL
,但为什么a2->m_i
可以是2.而且3更令人困惑,似乎函数createAonstack()
与a2无关。
答案 0 :(得分:2)
你说
根据我的理解,应该解构在函数
createA()
中创建的对象,并且它返回的指针应该指向NULL
,但为什么a2->m_i
可以是2
。
确实
在函数
createA()
中创建的对象应该被解构
并非如此
并且它返回的指针应该指向
NULL
createA
返回的指针非NULL,即使它是在调用函数中使用的无效指针。
但为什么
a2->m_i
可以是2
。
这纯属巧合。它确实是未定义的行为。取消引用a2
时会发生任何事情。
答案 1 :(得分:1)
函数createA()
返回一个局部变量上的指针,该函数在退出函数时被销毁,因此任何事情都可能发生,直接崩溃,或者更糟糕的是,程序将像所有事情都正常一样工作。
正如Bjarne Stroustrup所说:C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off.
答案 2 :(得分:0)
作为一个快速提示,一些更加可区分的命名约定可能有助于将来的可读性,因为我个人觉得它有点难以理解。
然而,据我所知,这是一个范围问题。 CreateA()生成一个本地指针,当它离开该函数的范围时,它就会丢失。所以你实际访问的内容基本上是随机的。