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

Bon*_*ngo 3 c++ visual-studio visual-studio-2012

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

CPrice price = CPrice();
Run Code Online (Sandbox Code Playgroud)

初始化通常应该如下所示

CPrice price;
Run Code Online (Sandbox Code Playgroud)

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

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

Ad *_*d N 6

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


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

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();
Run Code Online (Sandbox Code Playgroud)

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

  • 很可能该副本将被省略,它将与第二个示例相同. (2认同)