MyClass obj = MyClass();'MyClass()'在这里指的是临时对象吗?

MyClass obj = MyClass(); Does 'MyClass()' refer to a temporary object here?

本文关键字:MyClass 临时对象 obj 在这里      更新时间:2023-10-16

考虑不涉及复制省略的情况(C++17 之前(。

从 cpp首选项(再次假设 C++14(:

在以下情况下会创建临时对象:

  • 将引用绑定到 prvalue
  • 从函数返回 prvalue
  • 创建 PR值的转换
  • λ表达式
  • 需要转换初始值设定项的副本初始化
  • 构造 std::initializer_list 的列表初始化
  • 引用初始化为不同但可转换的类型或位域。

除了第一种情况之外,所有情况似乎都无关紧要,第一种情况似乎意味着C++式引用绑定(int &&x = 5;顺便说一句,在这种情况下我不明白在完整表达式结束时销毁临时语句的说法......,对象 5 所指的似乎没有在语句末尾被销毁(。

因此,据我了解,临时对象的概念仅包括那些保证被存储的对象(由于可能的省略,在我的情况下并非如此(。我说的对吗?否则我在这里误解了什么?

顺便说一句,MyClass()4int x = 4;上(或2 + 2int x = 2 + 2;(之间有什么区别吗?就像也许我错了,第一个确实指的是一个临时对象,而其他两个则没有......

C++14 标准[1] 在 12.2 中关于临时对象([class.temporary](说:

类类型的临时在各种上下文中创建:将引用绑定到 prvalue ([...](,返回 一个 prvalue ([...](,一个创建 prvalue 的转换 ([...], 5.4(, 抛出异常 ([...](, 以及在某些初始化中 ([...](。

MyClass obj = MyClass();中,MyClass()是函数表示法中的显式类型转换,因此它是一个临时对象,因为它属于"创建 prvalue 的转换"。

这不适用于int x = 4;中的4,因为该规则指的是"类类型",但int是"基本类型"。

此外,8.5 初始值设定项 ([dcl.init]( 将子句 (17.8( 中非类类型初始值设定项的语义定义为

否则,正在初始化的对象的初始值是初始值设定项的(可能已转换的(值 表达。[...]

而对于类类型,将调用(复制(构造函数。因此,对于类类型,您需要一个(临时(对象来复制,但对于"其他"类型则不需要。

[1]:实际上是 N4296,但这应该不会有什么区别

是的,它会创建一个临时的,因为这是一个显式转换,会创建一个 prvalue。

在上下文MyClass obj = MyClass();MyClass()prvalue。从您提供的 qoute 来看,它与"创建 prvalue 的转换">的情况相匹配,所以是的,创建了一个临时的。

实际上编译器会将这一行MyClass obj = MyClass();转换为:(假设MyClass具有未删除的默认和复制构造器(

MyClass _tmp{};  // (default-constructed)
MyClass obj = _tmp; // (copy-constructed)

第一行调用:MyClass::MyClass(this=&_tmp)

第二行调用:MyClass::MyClass(MyClass const&=tmp, this=&obj)