问题
Foo f1 = Foo(); // (1) Ok
Foo f2 = Foo; // (2) Compiler error
Foo *p1 = new Foo(); // (3) Ok
Foo *p2 = new Foo; // (4) Ok. Why??
I was wondering why there exists two ways to initialize pointers. It looks a little inconsistent. Is there some logical reason, and if so, what? Or, maybe it's some kind of legacy? And if so, What is the origin of such notation?
回答1:
It's a bit... complicated, to say the least.
When dealing with objects, both notations are equivalent. When dealing with primitive types (such as int
), (3)
will initialize (zero fill) the value, while (4)
will not (the value will be left undefined).
For automatically allocated objects, this:
Foo f1;
Declares and initializes a Foo
object using the default constructor. This:
Foo f2 = Foo();
Declares and initializes a Foo
object using the copy constructor, essentially copying the value of a temporary object (the Foo()
), which is built with the default constructor.
回答2:
I give you that it seems illogical, but if you think about the possible meanings, it makes a lot of sense.
Without knowing what Foo
might be, neither a human nor the compiler (here, the human perspective is more important) would be able to determine if Foo f2 = Foo;
is a) creating a new temporary Foo
object and copy constructing another one with it or b) assigning the value of a variable Foo
to the copy constructed object (f2
). It may seem obvious for us because our convention tells us that Foo
must be a type as it is capitalised, but in general it is not that simple (again: this mainly applies to a human reader that does not necessarily have the whole source code memorised).
The difference between (2)
and (4)
is that for the latter, only one interpretation is admissible, because new var
(where var
is a variable) is not a legal expression.
回答3:
The equivalent of 4 for scope-based resources is actually just
Foo f;
The legacy reason for the differences is essentially that in C, primitive types, such as int
, were not default-initialized to something useful. C++ inherited this behaviour for performance reasons- at the time. Of course, now, it's a trivial amount of processor time to expend. In C++, they introduced a new syntax by which it would always be initialized- the brackets.
int i = int();
i
is always guaranteed to be 0.
int i;
The value of i
is undefined.
This is the exact same as for the pointer variety, just with some new
:
int* i = new int(); // guaranteed 0
int* i = new int; // undefined
来源:https://stackoverflow.com/questions/7961015/variable-initialization-pointer-and-value