我今天看到了一个我不熟悉的类的c ++初始化。
CPrice price = CPrice();
初始化通常应该如下所示
CPrice price;
我猜想第一个应该抛出错误或其他东西。
这里发生了什么?我猜这个变量在堆栈上,因为它没有用new
进行初始化。
我使用Visual studio express 2012和microsofts c ++编译器。它可能是微软编译器特定的东西,因此允许吗?
答案 0 :(得分:5)
两行都非常精细,从客户端代码的角度来看,最终具有相同的可观察行为:price
是CPrice
类型的默认构造变量,当然在堆栈上分配。
如果你想进入技术细节,它们并不相同:
CPrice price;
是price
类型的变量CPrice
的默认初始化。这是一个用户类型(即一个类),所以它总是意味着对默认构造函数的调用。
CPrice price = CPrice();
是一个复合表达式,可以完成两件事:
CPrice()
:初始化和匿名CPrice
对象(在堆栈上),通过直接初始化(它调用带有()
的构造函数)。由于括号为空,因此将调用默认构造函数。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关键字,那么分配就在堆栈上(对于像这样的简单事情)。