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.