Reputation: 2732
I'm learning C++ (coming from Java) and this is bugging the hell out of me, say I have...
class Foo {
public:
Bar &x; // <- This is a ref, Bar is not instantiated (this is just a placeholder)
Bar *y; // <- This is a pointer, Bar is not instantiated (this is just another placeholder)
Bar z; // <- What is this???
};
class Bar {
public:
Bar(int bunchOfCrap, int thatNeedsToBeHere, double toMakeABar);
};
In this example Bar has one constructor that needs a bunch of fields specified in order to create a "Bar." Neither x, nor y creates a Bar, I understand that x creates a reference that can be pointed to a Bar and that y creates a pointer that can also represent a Bar.
What I don't understand is what exactly z is.
Is it a Bar? And if so, how can it be given Bar's only constructor?
Is it a Bar sized chunk of memory belonging to instances of Foo that can be initialized into a Bar?
Or is it something else?
Thanks!
Upvotes: 0
Views: 277
Reputation: 185862
z
is an instance of Bar
, and must be constructed when Foo
is, thus:
class Foo {
public:
Foo(…)
: x(<instance of or reference to Bar>),
y(<pointer to Bar>), // optional
z(<Bar ctor params>)
{ … }
Note that both x
and z
must be initialized during construction, whereas it is legal (albeit questionable) to omit y
's initialization.
z
occupies the same memory as the parent Foo
instance, but it is an instance of Bar
, not just a Bar
-sized chunk of memory.
Upvotes: 1
Reputation: 179432
For pedagogical reasons, let's try to compile this code:
class Bar {
public:
Bar(int bunchOfCrap, int thatNeedsToBeHere, double toMakeABar);
};
class Foo {
public:
Bar &x; // <- This is a ref, Bar is not instantiated (this is just a placeholder)
Bar *y; // <- This is a pointer, Bar is not instantiated (this is just a *safer* placeholder)
Bar z; // <- What is this???
};
int main() {
Foo foo;
}
Output:
c++ uuu.cpp -o uuu
uuu.cpp:10:7: error: implicit default constructor for 'Foo' must explicitly initialize the reference member 'x'
class Foo {
^
uuu.cpp:14:10: note: declared here
Bar &x; // <- This is a ref, Bar is not instantiated (this is just a placeholder)
^
uuu.cpp:10:7: error: implicit default constructor for 'Foo' must explicitly initialize the member 'z' which does not
have a default constructor
class Foo {
^
uuu.cpp:16:9: note: member is declared here
Bar z; // <- What is this???
^
uuu.cpp:2:7: note: 'Bar' declared here
class Bar {
^
uuu.cpp:21:9: note: implicit default constructor for 'Foo' first required here
Foo foo;
^
2 errors generated.
make: *** [uuu] Error 1
As it says, you must initialize both the member reference Bar &x
and the member variable Bar z;
, because Bar
doesn't have a default constructor. y
doesn't have to be initialized, and it will default to NULL
.
Both x
and y
indirectly refer to the object. You can't change what x
refers to (so it must be initialized when Foo
is instantiated). You can change what y
refers to. z
is a Bar
-sized chunk of memory which lives inside Foo
; for you to legally declare a member variable like this, you have to put the complete definition of Bar
before Foo
so that the compiler knows how big Bar
is.
Upvotes: 3
Reputation: 45410
Is it a Bar? And if so, how can it be given Bar's only constructor?
Yes, z is a bar. If Bar
has no default constructor you have to initialize Bar
in Foo member initializers list
. Below sample ignores x, y initialization:
Foo::Foo(int param1, int param2, int param3)
: z(param1, param2, param3)
{
}
Is it a Bar sized chunk of memory belonging to instances of Foo that can be initialized into a Bar?
Yes, Bar object is aligned inside Foo object
Upvotes: 1
Reputation: 6043
z
is a value identifier of type Bar
. This will generate a compiler error if you have not defined a default constructor (the compiler normally does this but it won't if you have defined at least one construction -> which you have).Foo
is allocated.Upvotes: 1