为什么没有为匿名对象调用析构函数
Why destructor is not getting called for anonymous objects?
在工作时,我遇到了一段奇怪/令人困惑的代码,我觉得它与匿名对象生命周期概念有关。以下是代码示例:
#include<iostream>
#include<string>
class A {
private:
int i;
std::string s;
public:
A(int ii, std::string ss = "Hello") { i = ii; s = ss; }
void Display() { std::cout<<i<<"n"; }
~A() { std::cout<<"A::~A()"<<"n";}
};
void function()
{
A a = 1;
//A a = A(1);
a.Display();
}
int main()
{
function();
return 0;
}
VS2010中的输出1(如果A A=1)
1
A::~A()
VS2010中的输出2(如果A A=A(1))
A::~A()
1
A::~A()
output2完全有意义,因为析构函数被调用两次(包括匿名对象)。
然而,output1让我感到困惑,无法理解为什么析构函数只被调用一次(不用于匿名)对象。
A a = 1;
上面的行将调用类A
的复制构造函数(A(const A& rhs)
),并且编译器应该使用参数1
为其创建匿名对象。如果是这种情况,析构函数应该被调用两次。
有人能向我解释一下这种行为吗?。可能是我错过了一些显而易见的东西。
A a = A(1);
等效于A a = 1;
。然而,在这两种情况下,都可能出现复制省略:A(1)
实际上是直接构建到a
中的,而不是单独构建然后复制或移动。
由编译器决定是否在任何允许的场景中执行副本省略(如上面的链接所述)。
编译器正在为A a = 1
消除副本,但不为A a = A(1);
消除副本,gcc在这两种情况下都可以消除副本,这可以用-fno-elide-constructors
进行测试。
相关文章:
- 对RValue对象调用的LValue ref限定成员函数
- 检查哪个对象调用了另一个对象的对象方法
- 在 C++ 的 Switch Case 中创建对象后对对象调用方法
- 从 Base 引用对象调用派生类的成员
- 为什么为未删除的对象调用析构函数?
- Qt c++不会为所有对象调用move_slot.为什么?
- 使用在堆栈上创建的对象调用虚拟函数
- 使用基类对象调用Dervied Class函数
- C++:允许临时对象调用非常量成员函数的设计理念是什么?
- 从类中的对象调用类中的函数的最佳方法
- 派生对象调用的 Base 方法的模板推导
- 如何使用单个对象调用具有相同名称的两个类函数
- 是否可以从另一个类对象调用一个类函数而不继承第一个类
- 如果类没有任何成员变量,则通过临时对象调用类的成员函数的开销是多少?
- 如何对动态数组中的某些对象调用析构函数
- 如何从列表中存储的对象调用成员函数
- 从线程内的对象调用静态方法
- 从成员对象调用方法
- 当包含它的对象调用其析构函数时,unique_ptr是否未分配
- 从对象调用成员对象,错误:引用非常量值的初始值必须是左值