2013-04-13 49 views
0

请考虑下面的代码片段。在C++中意外调用析构函数

#include<iostream> 

using namespace std; 

class A 
{ 
private: 
    int *x; 
public: 
    A(int a) 
    { 
    cout<<"creating "<<a<<" "<<this<<endl; 
    x = new int; 
    *x = a; 
    } 

    A(A *a) 
    { 
    this->x = a->x; 
    } 

    ~A() 
    { 
    cout<<"destroying "<<x<<endl; 
    delete x; 
    } 

    A *operator+(A a) 
    { 
    return new A(*x + *(a.x)); 
    } 

    void display() 
    { 
    cout<<*x<<endl; 
    } 
}; 

int main() 
{ 
    A a(5); 
    A b(10); 
    A c = a + b; 

    cout<<"control returns to main"<<endl; 
    a.display(); 
    b.display(); 
    c.display(); 
    return 0; 
} 

它产生以下输出。

creating 5 0xbffd6710 
creating 10 0xbffd6714 
creating 15 0x9273028 
destroying 0x9273018 
control returns to main 
5 
0 
15 
destroying 0x9273038 
destroying 0x9273018 
destroying 0x9273008 

我不明白为什么在控件返回到主函数之前调用析构函数。更重要的是,为什么要拨打b?如果在由operator+返回的新对象上调用它,它将是可以理解的,因为当控件离开对象的范围时调用析构函数。

+1

副本副本副本副本副本副本副本副本副本 –

+0

尝试输出'this'(代替或补充'x')在'〜A'。 –

+1

另外,你不应该返回'operator +'的指针。现在正在泄漏。 –

回答

6
A *operator+(A a) 
    { 

接收值。当

a + b; 

遇到创建的b新副本,并传递给operator+(A a)

你没有看到一个新的建造,因为你没有一个拷贝构造函数实现,编译器创建它也意味着您。否则,您会看到另外一个正在创建。

如果你不是让你operator*采取这样

A *operator+(A& a) 
    { 
    return new A(*x + *(a.x)); 
    } 

参考,你不会看到被破坏了,因为没有创建副本。

2

您:

  • 不输出为拷贝构造函数(这在目前是编译器生成的)

  • “创造”(或者更确切地说,妥善处理您的资源)

    看到临时a + b被摧毁

0

你实现拷贝构造函数和+运算符是错误的。试试这个:

class A 
{ 
private: 
    int *x; 
public: 
    A(int a) 
    { 
    cout << "creating " << a << " " << this << endl; 
    x = new int; 
    *x = a; 
    } 

    A(const A &a) 
    { 
    cout << "copying " << *(a.x) << " " << this << endl; 
    x = new int; 
    *x = *(a.x); 
    } 

    ~A() 
    { 
    cout << "destroying " << *x << " " << this << endl; 
    delete x; 
    } 

    A operator+(const A &a) 
    { 
    return A(*x + *(a.x)); 
    } 

    void display() 
    { 
    cout << *x << endl; 
    } 
};