I was testing which constructors are called in when a derived and then base class objects are created. My program couted 0 if it was the base class and 1 if it was the base class. I ran it and it returned 01 for the derived class and 0 for the base class. The derived class surprised me greatly because it seems as thought it calls the base class and then the derived class. Is this information correct?

Dani AI

Generated

raised the right observation and gave a good demonstration. The formal rule is a bit richer than the short list in the thread: when creating an object of the most‑derived class, C++ first initializes virtual base subobjects (if any), then non‑virtual direct bases in the order they appear in the base‑specifier list, then nonstatic data members in the order they are declared in the class, and only then runs the body of the derived constructor. Destruction runs in the exact reverse order. This ordering guarantees that every base and member is fully constructed before any code that might use it runs (see cppreference: Order of initialization).

That may feel inefficient, but it is required for correctness. The language gives predictable object invariants: base constructors set up the base part and members are ready before the derived constructor runs. If construction cost is the concern, the usual solutions are design changes rather than bypassing the rules: use pointers or smart pointers (lazy allocate heavy members), use std::optional for delayed construction, or prefer composition where you control when a component is new'd. These keep the heavy work out of the immediate object construction without breaking object semantics.

About initializing “a variable that wasn't inherited”: a derived constructor cannot directly initialize a base class’s individual members. The derived initializer list may call a base constructor (for example Derived() : Base(42), y(0) {}), but you cannot write something like Derived() : x(42) {} to initialize x if x is a member of Base — that is a compile‑time error. Only the base class’s constructor initializes its own subobjects.

Quick tips: enable compiler warnings about initializer order (GCC/Clang -Wreorder), keep initializer lists matching declaration order to avoid surprises, and prefer lazy construction or move semantics if construction cost matters.

Recommended Answers

All 5 Replies

The order of class object constuction (reduced C++ rules, apply recursively):

1. direct base class(es) constructor(s)
2. this nonstatic data member(s) constructor(s)
3. this constructor

Revert the order for destruction.

Try this:

class Member { public:
Member(const char* where = ""):whom(where) {
        cout << "Member " << where << " ctor\n";
    }
    ~Member() { cout << "Member " << whom << " dtor\n"; }
    std::string whom;
}; 

class Base { public:
    Base():m("Base") { cout << "Base ctor\n"; }
    ~Base(){ cout << "Base dtor\n"; }
    Member m;
};
class Derived: public Base
{ public:
Derived():mm("Derived") { cout << "Derived ctor\n"; }
    ~Derived(){ cout << "Derived dtor\n"; }
    Member mm;
};

Yes but doesn't it seem terribly inefficient to call all of the constructors in that order automatically? Is there any way to stop it?

Yes but doesn't it seem terribly inefficient to call all of the constructors in that order automatically? Is there any way to stop it?

Yes, of course: stop using this inefficient ;) language C++, switch to Visual Basic (or better to Fortran 66)...
Yet another way to go: never declare class variables and don't use operator new. No declarations - no constructors...

Also, What happens if the constructor tries to initializ a variable that wasn't inherited?

Also, What happens if the constructor tries to initializ a variable that wasn't inherited?

???
Can you give an example of this mysterious case?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.