C++ 何时自动调用析构函数?
我正在玩C++ 何时自动调用析构函数?,c++,C++,我正在玩析构函数和operator=,输出对我来说很奇怪 两个版本的主要功能: int main() { B b1; B b2; b2=b1; cout<<"---"<<endl; return 0; } 现在操作符=returnB&而不是B,输出不一样;析构函数调用两次,而不是以前的三次。为什么? B类 { 公众: B&B操作员=(B&b1) { cout代码工作正常,如预期。在第一种情况下,在“operator=”之后调用析
析构函数
和operator=
,输出对我来说很奇怪
两个版本的主要功能:
int main()
{
B b1;
B b2;
b2=b1;
cout<<"---"<<endl;
return 0;
}
B&
而不是B
,输出不一样;析构函数调用两次,而不是以前的三次。为什么?
B类
{
公众:
B&B操作员=(B&b1)
{
cout代码工作正常,如预期。在第一种情况下,在“operator=”之后调用析构函数,因为您返回的是B:
B operator=(B& b1)
{
cout<<"operator="<<endl;
return b1;
}
但是,在第二种情况下,赋值运算符重载的返回类型为B&,复制构造函数将永远不会被调用,因为它将返回对它接收的对象的引用,而不是副本。因此,对于在main()方法中创建的对象b1和b2,析构函数只会被调用两次。
希望这能回答您的问题。在第一种情况下,您还有一个实例:
int main()
{
B b1;
B b2;
b2=b1; <---- here b2.operator=(b1) returns another B instance
(its a copy of b1)
cout<<"---"<<endl;
return 0;
}
使实例在作用域结束前保持活动状态。在这种情况下,您将看到在打印--
后调用析构函数
还要注意的是,两个操作符都不正确,因为操作符应该返回对*this
的引用,而不是对其他实例的引用。(PaulMcKenzie在评论中已经提到过,请在此处重复,以确保不会丢失)因为在一种情况下,您的操作符=
返回一个新创建的实例(它不应该返回),而在另一种情况下它不返回。这不是很明显吗?顺便说一句“这不是很明显吗?”这并不意味着冒犯,只是试图理解您丢失了什么两个函数都写得不正确,因为操作符=
应该返回对当前对象的引用,而不是一个全新的对象,也不是对另一个对象的引用。您知道这在引擎盖下到底做了什么吗??:b2=b1;@tobi303 I sti我不明白为什么在第二种情况下,析构函数没有被调用。@PaulMcKenzie你的意思是我应该为操作符=
的每次调用在堆上分配内存,这样我就可以返回他的引用了吗?@ΦXocę웃 Пepeúpaツ 因为您返回的是B对象的本地副本:“没有本地副本,否则将调用析构函数两次(一次用于本地,一次用于主实例中返回的实例)。是的,因为第一种情况下的返回类型(理想情况下不应该是这样的)。您显式地告诉函数返回“B”而不是“B&”,因此它调用复制构造函数并返回实例而不是引用。是的,但是操作符=
中没有本地副本。同意,我实际上不应该将其称为“本地副本”。
B operator=(B& b1)
{
cout<<"operator="<<endl;
return b1;
}
class B
{
public:
B operator=(B& b1)
{
cout<<"operator="<<endl;
return b1;
}
~B()
{
cout<<"destructor"<<endl;
}
B(const B& b1){
cout << "Copy constructor called" << endl;
}
B(){}
};
operator=
Copy constructor called
destructor
---
destructor
destructor
int main()
{
B b1;
B b2;
b2=b1; <---- here b2.operator=(b1) returns another B instance
(its a copy of b1)
cout<<"---"<<endl;
return 0;
}
B b3 = (b2=b1);