繁体   English   中英

C++ 对象初始化(堆栈)

[英]C++ Object Initialization (Stack)

我今天看到了一个我不熟悉的类的 c++ 初始化。

CPrice price = CPrice();

初始化通常应该是这样的

CPrice price;

我会猜到第一个应该抛出错误或其他什么。 这里会发生什么? 我猜这个变量在堆栈上,因为它没有用new初始化。

我将 Visual Studio express 2012 与 microsofts c++ 编译器一起使用。 它可能是微软编译器特定的,因此被允许吗?

这两行都非常好,从客户端代码的角度来看,最终具有相同的可观察行为: priceCPrice类型的默认构造变量,当然分配在堆栈上。


如果您想深入了解技术细节,它们并不相同:

CPrice price; CPrice类型的变量price的默认初始化。 这是一个用户类型(即一个类),所以它总是意味着对默认构造函数的调用。

CPrice price = CPrice(); 是一个复合表达式,它做两件事:

  • CPrice() :通过直接初始化(它使用()调用构造函数CPrice()初始化和匿名CPrice对象(在堆栈上)。 由于括号是空的,这将调用默认构造函数。
  • 然后它复制初始化(在 C++11 之前)/移动初始化(C++11 以后可用)一个CPrice类型的变量price ,复制自/移动自对象是匿名CPrice实例。

最长分配强制CPrice存在复制构造CPrice ,否则代码将出错。 但是允许编译器跳过复制构造并优化它,通过发出与最短形式相同的代码。
此外,在 C++11 中,如果CPrice存在移动构造CPrice ,则在这种情况下将使用它代替复制构造函数(即,如果此操作没有完全删除)。

因此,唯一可感知的区别是,即使CPrice不可复制构造,最短的形式也会编译。 这两种形式都要求CPrice是默认可构造的。


一个或多或少相关的精度,来自另一个答案。 您可能会认为这样的假设中间立场声明是相同的:

CPrice price();

然而,它实际上完全不同:这个声明price是一个不带参数(空括号)的函数,并返回一个CPrice 它通俗地称为最令人头疼的解析

当实例已经声明时,赋值正在调用赋值运算符(如果未删除)。 第一行声明了 AND 显式调用了一个构造函数,在堆栈上没有真正的帮助,但在多态性的堆中更有帮助。 第二行直接调用它的默认构造函数(如果没有删除并且也没有实现 operator() )

如果您仍然想知道运算符 = ,那么在类声明中显式声明
CPrice & operator = (const CPrice &) = delete;

这两行做的事情完全一样。 它们都调用默认构造函数(一个没有参数的构造函数)。 同样有效的可能是CPrice price(); ,因为这个和第一个你允许你推送参数,如果有一个构造函数接受它们,而你的第二个不会。 同样是的,如果不使用 new 关键字,则分配在堆栈上(对于像这样的简单事情)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM