gpt4 book ai didi

c++ - 为什么析构函数调用三次?

转载 作者:太空狗 更新时间:2023-10-29 20:23:36 25 4
gpt4 key购买 nike

我正在研究 RVO/Copy-Constructor/Destructor 并随机检查代码。我在这里有点困惑为什么析构函数被调用了三次……??

#include <iostream>
using namespace std;
class A{
public:
A(){
cout << "Simple Constructor" << endl;
}
A(const A& obj){
cout << "Copy Constructor " << endl;
}
A operator =(A obj){
cout << "Assignment Operator" << endl;
}
~A(){
cout << "Destructor " << endl;
}
};
A fun(A &obj){
cout << "Fun" << endl;
return obj;
}
int main(){
A obj;
obj=fun(obj);
cout << "End" << endl;
return 0;
}

输出:

Simple Constructor // ok
Fun // ok
Copy Constructor // ok for =
Assignment Operator // ok
Destructor // ok for =
Destructor // why here destructor called?
End // ok
Destructor // ok for main

我原以为 Destructor 会被调用两次。

一个用于(=) 运算符的 对象。

第二个用于 int main() 的 对象。

为什么第三次调用它?又如何?

最佳答案

     A operator =(A obj){
cout << "Assignment Operator" << endl;
}

您将函数 A::operator= 声明为具有返回类型(在本例中为 A 的实例),但实现没有返回语句。 这是未定义的行为

您实际上是在询问对未定义行为的响应。答案是“一切皆有可能”。在您的情况下,对于您的编译器和系统,您对析构函数的调用比对构造函数的调用多一次。你很幸运,你的程序没有创建 nasal demons或删除您的硬盘。

解决方案很简单:不要调用未定义的行为。编写复制赋值运算符的规范方法是让返回类型成为类的引用并返回 *this:

     A& operator =(A obj){
cout << "Assignment Operator" << endl;
return *this;
}

通过此更正,您将看到对各种构造函数的调用和对析构函数的调用之间的平衡。

假设您改为使用非标准的复制赋值运算符(但具有正确编写的 return 语句):

     A operator =(A obj){
cout << "Assignment Operator" << endl;
return *this;
}

您会再次看到对构造函数和析构函数的调用平衡。您将看到多少次调用取决于您的编译器和优化级别。

关于c++ - 为什么析构函数调用三次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32411066/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com