#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 ?
为什么“t b = 5;”不会叫析构函数? “t b = 5”如何运作?是否首先使用构造函数“t(int x)”创建一个临时对象(类t),然后使用复制构造函数“t(const t&amp;)”来创建b? 如果是这样的话,它为什么不调用临时对象的析构函数呢?
答案 0 :(得分:2)
为什么“t b = 5;”不会叫析构函数?
执行此操作时:
t b=5;
你得到copy initialization。在语义上,调用隐式转换构造函数t(int)
,然后调用复制构造函数t(const t&)
来实例化b
。但是,编译器允许elide the copy,这就是您的情况。对象在适当的位置构建,无需复制构造。这就是你没有看到析构函数调用的原因。但是你的类仍然需要一个拷贝构造函数来编译该代码:copy elision是可选的,一些代码编译是否应该依赖于编译器是否正在执行elision。
如果你说过
t b(5);
然后会有一个直接初始化,没有复制省略,只有一个构造函数调用。您的类不需要复制构造函数来编译此代码。
答案 1 :(得分:1)
由于您没有使用int
的作业运算符,b = 3;
被解释为
`b.operator=(t(3));`
这将创建一个临时t
实例,并在赋值返回后销毁它。这就是打印第一个de
行的内容。最后,在main
的末尾,b
超出范围,调用其析构函数并打印第二行。
答案 2 :(得分:0)
也许你的程序中有一点痕迹可以帮助你理解什么是happing:
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
}