C++ Object Initialization (Stack)

非 Y 不嫁゛ 提交于 2019-12-13 14:22:26

问题


I saw today a c++ Initialization of a class which I am not familiar with.

CPrice price = CPrice();

The Initialization should normally look like this

CPrice price;

I would have guessed that the first one should throw an error or something. What happens here ? I would guess that the variable is on the stack because it wasn't initialized with new .

I use Visual studio express 2012 with microsofts c++ compiler. Is it maybe something which is microsoft compiler specific and thus allowed ?


回答1:


Both lines are perfectly fine, and end up with the same observable behaviour from the client code point of view: price is a default constructed variable of type CPrice, of course allocated on the stack.


If you want to go into the technicalities, they are not identical:

CPrice price; is a default initialization of a variable price of type CPrice. This is a user type (i.e., a class), so it always mean a call to the default constructor.

CPrice price = CPrice(); is a compound expression that does two things:

  • CPrice(): initializes and anonymous CPrice object (on the stack), by direct initialization (it invokes a constructor with the ()). Since the parentheses are empty, this will call the default constructor.
  • It then copy initializes (before C++11) / move initializes (available to C++11 onward) a variable price of type CPrice, the copied-from/moved-from object being the anonymous CPrice instance.

The longest allocation forces that a copy constructor exists for CPrice, or the code will be in error. But the compiler is allowed to skip the copy construction and optimise it away, by issuing the same code than with the shortest form.
Additionally, in C++11, if a move constructor exists for CPrice, it will be used in place of the copy constructor in this case (that is, if this operation is not entirely removed anyway).

So the only perceivable difference is that the shortest form will compile even if CPrice is not copy constructible. Both forms require CPrice to be default constructible.


One more more or less related precision, coming from the other answer. You could think that an hypothetical middle ground declaration like this would be the same:

CPrice price();

Yet, it is actually completely different: this one declares price to be a function taking no argument (the empty parentheses), and returning a CPrice. It is colloquially known as the most vexing parse.




回答2:


the assignation is calling the assignment operator (if not deleted) when the instance has already been declared . The first line declares AND explicitly calls a constructor , not really helpful on stack but more in the heap with polymorphism . The second line calls directly its default constructor (if not deleted and if no operator() implemented too )

If you still wonder for the operator = , then explicitly declare in the class declaration
CPrice & operator = (const CPrice &) = delete;




回答3:


The two lines do exactly the same thing. They both call the default constructor (one with no arguments). Also valid could have been CPrice price();, as this and the first one you have allow you to push arguments if there is a constructor that takes them, whilst your second one would not. Also yes, if the new keyword is not used, then the allocation is on the stack (for simple things like this).



来源:https://stackoverflow.com/questions/32272409/c-object-initialization-stack

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!