0
#include <iostream>

using namespace std;

class t{
private:
int * arr;

public:
    t() { arr=new int[1]; arr[0]=1;}
    t(int x) {arr=new int[1]; arr[0]=x;}
    t(const t &);
    ~t() {cout<<arr[0]<<"   de"<<endl; delete [] arr;}
    t & operator=(const t & t1){arr[0]=t1.arr[0];return *this;}
    void print(){cout<<arr[0]<<endl;}

};
t::t(const t & t1) {arr=new int[1];arr[0]=t1.arr[0];}

int main(){

   t b=5;
   cout<<"hello"<<endl;
   b.print();
   b=3; 
   b.print();
   return 0;
}

为什么结果是

hello
5
3   de 
3
3   de ?

为什么“tb = 5;” 不会调用析构函数?“tb = 5”如何工作?它是否首先使用构造函数“t(int x)”创建一个临时对象(t类),然后使用复制构造函数“t(const t &)”创建b?如果是这种情况,为什么它不调用 temp 对象的析构函数?

4

3 回答 3

2

为什么“tb = 5;” 不会调用析构函数?

当你这样做时:

t b=5;

你得到复制初始化。语义t(int)上调用隐式转换构造函数,然后t(const t&)调用复制构造函数进行实例化b。但是,允许编译器省略 copy,这就是您的情况。对象是就地构造的,不需要复制构造。这就是您看不到析构函数调用的原因。但是您的类仍然需要一个复制构造函数来编译该代码:复制省略是可选的,并且某些代码是否编译不应取决于编译器是否执行省略。

如果你说过

t b(5);

然后将进行直接初始化,没有复制省略,并且只有一个构造函数调用。您的类不需要复制构造函数来编译此代码。

于 2013-10-07T04:42:42.137 回答
1

由于您没有使用 , 的赋值运算符intb = 3;因此被解释为

`b.operator=(t(3));`

这将创建一个临时t实例,并在分配返回后将其销毁。这就是打印第一de行的内容。最后,在 , 结束时mainb它的析构函数被调用并打印第二行。

于 2013-10-07T04:39:10.347 回答
0

也许您的程序中的一点痕迹可以帮助您了解正在发生的事情:

int main(){
  t b=5;  // as you expected, this call the constructor of your object. 
  cout<<"hello"<<endl;
  b.print();  // as you could see, this call print() and print 5
  b=3;   // this is where the confusion begins. You didn't provide a way 
         // from your object to make an assigment from an integer, but you 
         // provide a way to construct an object from integer. So, your 
         // compiler will construct a temporary object, with 3 as parameter 
         // and use this object to do this assignment. Once this is a 
         // temporary object, it will be destructed at the end of this 
         // operation. That is why you are getting the message: 3   de
  b.print(); // print 3 as expected
  return 0;  // call the destruct from the object that was assigned before
}
于 2013-10-07T04:40:37.577 回答