Given the code sample:
class B {
//Some contents.
};
class C {
private:
B& b;
};
class A {
private:
B b;
C c;
};
Class C has a reference to a b, so it needs to be initialized with it. Class A contains an instance of B and an instance of C.
My question is: Can I initialize the C instance in A with the B instance in A (assuming I did bother to put the constructors in)? Secondly, do I need to perform any explicit initialization of the B in A, or is it default initialized since its a class type within a class?
Member variables are initialised in the order that they are declared in the class declaration (even if you have them in a different order in the initialisation list of the constructor), so yes, by the time c
is being initialised, b
will be initialised, and you can use b
to initialise c
.
As Ricardo Cardenes notes, it will still work even if you declare c
before b
in the class definition (which means you will pass C::C
a reference to an uninitialised B
) however you cause undefined behaviour if you use the object inside C::C
. It's safer to declare b
first, because although you may not use b
inside C::C
now, you might in the future and forget that the reference refers to an uninitialised B
, and cause UB.
And no, you do not have to explicitly initialise b
(unless it is POD) unless you don't want it to be default-constructed. So this code would be what you want (again, if B
isn't POD):
A::A() : c(b) { }
To your first question: you can initialize it by writing constructors like this:
C::C(B& bInst): b(bInst){}
A::A():b(), c(b) {}
Of course if your constructor of C
actually uses b
(instead of just its address), you need to ensure that the initialization order stays the same, so b
must be declared before c
, since members are initialized in the order they are declared in (even if the initializaiton list puts them in a different order).
And no you don't need to explicitly initialize B, since it will be default constructed if you don't. Of course if B is a POD this means remaining it uninitialized (while explicitely initializing it using b()
in the initializer list of A()
would initialize it to 0
).
Can I initialize the C instance in A with the B instance in A (assuming I did bother to put the constructors in)
Sure.
Secondly, do I need to perform any explicit initialization of the B in A, or is it default initialized since its a class type within a class?
No, that's fine.
Yes, since C only contains a reference to a B and not a separate instance, you can put a constructor in C and let A.C.b reference A.B.
B and C inside A are both instantiated/constructed automatically when you create an instance of A.