#include <iostream>
using namespace std;
class Test
{
public:
Test() { cout << "Constructor is executed\n"; }
~Test() { cout << "Destructor is executed\n"; }
};
int main()
{
Test(); // Explicit call to constructor
return 0;
}
在上面的代码中,我们显式地调用构造函数,当显式调用构造函数时,编译器会创建一个无名的临时对象,并立即将其销毁。 为什么我们需要这个临时对象??
答案 0 :(得分:0)
因为构造函数&amp;析构函数有副作用。他们都打印东西。
如果它们没有副作用,那么编译器可能足够聪明,可以确定它实际上不需要创建临时值,并完全跳过它。
答案 1 :(得分:0)
您正在使用的功能类型转换表示法,Test(...)
,实际上意味着“从C ++ 98到C ++创建一个Test
类型的临时对象” 14。因此,根据请求创建临时,并调用构造函数以初始化对象。它不意味着“调用构造函数”。实际上,构造函数的执行永远不能与对象的创建分开。
在C ++ 17中,Test()
是一个实现的prvalue,因为它被用作废弃值表达式。在具体化时,创建临时对象,并调用构造函数。确实,构造函数的执行永远不会与创建对象分开发生。
答案 2 :(得分:0)
标准(C ++ 14)简要提到了临时对象的一些情况:
1. Binding a reference to a prvalue
2. Returning a prvalue
3. A conversion that creates a prvalue
4. Throwing an exception
5. In some initializations
您可以从stackoverflow获取prvalue
的说明。
我收集了Quora的情况。
答案 3 :(得分:0)
RE
“为什么我们需要这个临时对象?
......我们没有。编译器可以自由优化,只要效果就像一样,带有副作用的构造函数和析构函数已被调用。
编译器无法删除构造函数和析构函数的副作用,因为标准明确要求它不要删除构造或破坏有副作用的本地对象:
C ++11§3.7.3/ 3 basic.std.auto/3 :<强>” 强> 如果具有自动存储持续时间的变量具有初始化或具有副作用的析构函数,则不应该 在它的块结束之前被销毁,即使它看起来也不会作为优化被消除 不使用,但可以按照12.8中的规定消除类对象或其复制/移动。