簡體   English   中英

在C ++中意外調用析構函數

[英]Unexpected call to destructor in 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+返回的新對象上調用了它,那將是可以理解的,因為當控件超出對象范圍時將調用析構函數。

A *operator+(A a)
  {

按價值收取。 這意味着什么時候

a + b;

遇到b的新副本,並將其傳遞給operator+(A a)

您沒有看到新的構造方法,因為您沒有實現復制構造方法,而編譯器為您創建了它。 否則,您將看到另一個正在創建的A。

如果您改為讓您的operator*采用這樣的參考

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

您將不會再看到破壞,因為未創建任何副本。

您:

  • 不要為副本構造函數 (目前由編譯器生成)輸出“正在創建”(或實際上是正確處理資源)

  • 看到臨時的a + b被破壞了

復制構造函數和+運算符的實現錯誤。 嘗試以下方法:

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;
  }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM