C ++构造,解构和指向类对象的机制

时间:2014-06-20 15:56:27

标签: c++

#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无关。

3 个答案:

答案 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()生成一个本地指针,当它离开该函数的范围时,它就会丢失。所以你实际访问的内容基本上是随机的。