Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialization order issues

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?

like image 204
John Humphreys Avatar asked Jul 11 '26 00:07

John Humphreys


2 Answers

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) { }
like image 189
Seth Carnegie Avatar answered Jul 13 '26 15:07

Seth Carnegie


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).

like image 37
Grizzly Avatar answered Jul 13 '26 16:07

Grizzly