Richard Smith 的论文Guaranteed copy elision through simple value categories的这一部分在对象创建和对象初始化之间做出了重要区分(prvalues 在C++11中被定义为创建临时对象或值;它们在 C++17中被重新定义为初始化对象或值):
细化值类别的含义
现在我们对值类别有了一个简单的描述,我们可以重新考虑这些类别中的表达式应该如何表现。特别是,给定一个类 type
A
,表达式A()
当前被指定为创建一个临时对象,但这不是必需的:因为prvalue的目的是执行初始化,A()
创建临时对象不应该是表达式的责任. 如有必要,这应该由表达式出现的上下文执行。然而,在许多情况下,没有必要创建这个临时对象。例如:// make() is a prvalue (it returns "by value"). Therefore, it models the // initialization of an object of type NonMoveable. NonMoveable make() { // The object initialized by 'make()' is initialized by the following // constructor call. return NonMoveable(42); } // Use 'make()' to directly initialize 'nm'. No temporary objects are created. auto nm = make(); NonMoveable x = {5}; // ok today NonMoveable x = 5; // equivalent to NonMoveable x = NonMoveable(5), // ill-formed today (creates a temporary but can't move it), // ok under this proposal (does not create a temporary object)
我们得出结论,类或数组类型的纯右值表达式不应创建临时对象。相反,如果有必要,临时对象由表达式出现的上下文创建。需要创建(“物化”)临时对象的上下文如下:
- 当prvalue绑定到引用时
- 当对类纯右值执行成员访问时
- 对数组纯右值执行数组下标时
- 当数组纯右值衰减为指针时
- 当对类纯右值执行派生到基础的转换时
- 当prvalue用作丢弃值表达式时
请注意,这里的第一条规则已经存在于标准中,以支持非类、非数组类型的纯右值。不同之处在于,通过提议的更改,语言规则现在对于类和非类类型是统一的。
C ++中的对象创建和对象初始化有什么区别?
我一直认为它们是同义词,并且考虑到了这个对象模型:
|------------|--|----------------|----------|--------------|--|--------------|
<----------> <--------------> <--------> <------------> <------------>
storage object object object storage
allocation initialization lifetime finalization deallocation
<---------------------------------------------->
storage duration