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

时间:2015-08-28 13:37:19

标签: c++ visual-studio visual-studio-2012

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

CPrice price = CPrice();

初始化通常应该如下所示

CPrice price;

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

我使用Visual studio express 2012和microsofts c ++编译器。它可能是微软编译器特定的东西,因此允许吗?

3 个答案:

答案 0 :(得分:5)

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

如果你想进入技术细节,它们并不相同:

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

CPrice price = CPrice();是一个复合表达式,可以完成两件事:

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

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

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

另一个或多或少的相关精度来自另一个答案。您可以认为像这样的假设的中间声明将是相同的:

CPrice price();

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

答案 1 :(得分:-1)

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

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

答案 2 :(得分:-2)

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