Reputation: 4770
I have been reading "C++ primer". For the initialization of object, C++ supports 2 forms of initialization: direct and copy. but the book does not refer the initialization of reference. And in the book I have never seen the direct initialize(if exists) of a reference. All is the copy one like:
int i;
int &j = i;//but not int &j(i);which also works in my experiment
I want to know that is it the same that are going on underneath for the initialization of a reference. for the following codes:
string null_book = "9-999-99999-9";
the initialization progress is first create a temporary string object tmp(for instance) that will direct initialized with a c style string parameter, and then initialize the variable null_book with the copy Constructor. That make sense to me. for this one:
int &j = i;
will ref j be initialized the same way? That will be a temp reference it &t(for example) initialized by i and then initialize j with t? that doesnt make sense??? Why the book never use the direct initialization for reference? Thanks for your attention!
Upvotes: 8
Views: 895
Reputation: 100050
A reference in C++ is just a pointer wearing a funny hat. The statement:
TYPE& x = y;
is always equivalent to:
TYPE* const x = &y;
All references do is save you typing *
characters and declare your belief that there will never be a null. So the initialization is trivial, since it is an initialization of a pointer, not an object, and there is no complexity of objects, temporary or otherwise, to deal with.
This is the conceptual model; of course, there are optimizations. If you declare a function like:
void takeARef(FOO const& ref) { ... }
and call it, then the compiler is just going to pass a pointer into the function, and create nothing.
Upvotes: 4
Reputation: 157354
The main differences between direct-initialization and copy-initialization are covered in section 8.5, paragraph 17 of the standard. In general, the difference is that for class types in copy-initialization, explicit constructors are not considered (only converting constructors are considered) and a possibly elided copy is made; in direct-initialization explicit constructors are considered and the target is constructed directly. From section 8.5 of the standard:
14 - The form of initialization (using parentheses or
=
) is generally insignificant, but does matter when the initializer or the entity being initialized has a class type [...]
For non-class types (including references), direct-initialization and copy-initialization have similar semantics; for references, a reference binding occurs in either case, as specified in 8.5.3 References [dcl.init.ref]. Direct-initialization and copy-initialization of a reference only have different semantics where a conversion function is involved (13.3.1.6 Initialization by conversion function for direct reference binding [over.match.ref]); again, direct-initialization is allowed to invoke explicit conversion functions where copy-initialization is not.
So, in
int &j = i;
8.5.3p5 applies and the reference j
is bound directly to the lvalue i
. No temporaries are invoked.
In terms of complexity, references are closer to fundamental (primitive) types than to class types. Primitives are initialized without a temporary being constructed (8.5p17, last bullet) and in general references are too. This is probably why the book only uses the =
form for initialization of references; as with primitives, there is usually no difference and writing int i = x;
is usually clearer than int i(x);
.
Upvotes: 7
Reputation: 477040
The terms copy-initialization and direct-initialization are part of the grammar of C++. they don't immediately tell you what sort of code generation happens. The meaning of any grammatical construction is described by the standard, and the context of initialization there are lots of different particular consequences depending on the types of the things that are being initialized.
In particular, for primitive types, pointer types and reference types, both direct- and copy-initialization (the grammatical construct!) have the exact same effect. That is, fundamental and pointer types are initialized with the value of the initializer, and references are bound to the object referred to by the initializer:
int a1 = 5;
int a2(5); // same thing
Foo * p1 = &x;
Foo * p2(&x); // same thing
Bar & b1 = y;
Bar & b2(y); // same thing
(However, for user-defined types there is a distinction between direct- and copy-initialization, although it is a subtle one that is usually not important.)
Upvotes: 5