MyClass obj = MyClass();'MyClass()'在这里指的是临时对象吗?
MyClass obj = MyClass(); Does 'MyClass()' refer to a temporary object here?
考虑不涉及复制省略的情况(C++17 之前(。
从 cpp首选项(再次假设 C++14(:
在以下情况下会创建临时对象:
- 将引用绑定到 prvalue
- 从函数返回 prvalue
- 创建 PR值的转换
- λ表达式
- 需要转换初始值设定项的副本初始化
- 构造 std::initializer_list 的列表初始化
- 引用初始化为不同但可转换的类型或位域。
除了第一种情况之外,所有情况似乎都无关紧要,第一种情况似乎意味着C++式引用绑定(int &&x = 5;
顺便说一句,在这种情况下我不明白在完整表达式结束时销毁临时语句的说法......,对象 5 所指的似乎没有在语句末尾被销毁(。
因此,据我了解,临时对象的概念仅包括那些保证被存储的对象(由于可能的省略,在我的情况下并非如此(。我说的对吗?否则我在这里误解了什么?
顺便说一句,MyClass()
和4
在int x = 4;
上(或2 + 2
int 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)
- 在不复制临时对象的情况下延长其生存期
- 为什么当我们有常量引用时创建临时对象?
- 程序如何'remember'临时对象?
- 返回对临时对象的引用
- 防止临时对象文件访问 MSVC 中的磁盘
- 是否可以在C++中移动临时对象的属性?
- 通过引用传递临时对象
- 临时C++对象是否为左值?
- 临时对象:术语澄清
- 存储对(可能)临时对象的引用是否合法,只要引用不比对象存活?
- 临时对象有身份吗?
- 临时对象上的运算符重载
- 如何在没有 std::move 的情况下移动临时对象
- 临时对象在C++中是不可避免的吗?
- 编译错误:临时对象构造函数中缺少参数
- 为什么在按值返回时创建临时对象,而不是在按值传递给函数参数时创建临时对象
- 我试图创建临时对象的方式有错误吗
- 子表达式中临时对象的生存期
- 对临时对象的Const引用不会延长其生存期
- MyClass obj = MyClass();'MyClass()'在这里指的是临时对象吗?