2013-04-13 2 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)

Вы не видите новый один построен, потому что вы не конструктор копирования реализован и компилятор создал его для вы. В противном случае вы увидите еще одно созданное 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; 
    } 
}; 
Смежные вопросы