Question
In C++, what are the rules for calling a base class constructor from a derived class?
For example, in Java, the base constructor must be called as the first line of the subclass constructor. If you do not call it explicitly, Java inserts an implicit call to the no-argument super() constructor, which causes a compile error if that constructor does not exist.
How does this work in C++?
Short Answer
By the end of this page, you will understand how C++ constructs base classes from derived classes, when a base constructor is called automatically, how to explicitly choose which base constructor to call, and what order constructors run in. You will also see common mistakes and how this differs from Java.
Concept
In C++, a derived object is built in layers.
When you create an object of a derived class, C++ first constructs its base class subobject, then constructs the derived class's own members and body. This happens automatically as part of object construction.
The important rule is:
- Base class constructors are called before the derived class constructor body runs.
- You do not call the base constructor inside the body like a normal function.
- Instead, you choose the base constructor in the derived constructor's member initializer list.
Basic idea
class Base {
public:
Base(int x) {}
};
class Derived : public Base {
public:
Derived(int x) : Base(x) {}
};
Here, Base(x) is not a normal function call. It tells C++ which Base constructor should be used before Derived is finished being constructed.
If you do not specify a base constructor
If the derived constructor does not mention the base class in the initializer list, C++ tries to call the base class's default constructor.
class Base {
public:
Base() {}
};
class Derived : Base {
:
() {}
};
Mental Model
Think of a derived object like building a house on top of a foundation.
- The base class is the foundation.
- The derived class is the upper structure.
You cannot build the upper floor first and then decide what kind of foundation you wanted. The foundation must be poured first.
In C++, the member initializer list is where you tell the builder which foundation to use.
Derived(int x) : Base(x) {}
That means: "Before building the Derived part, first construct the Base part with x."
The constructor body runs only after that foundation already exists.
Syntax and Examples
Core syntax
Use the base class constructor in the derived constructor's initializer list:
class Base {
public:
Base(int value) {}
};
class Derived : public Base {
public:
Derived(int value) : Base(value) {}
};
Example 1: Explicitly calling a base constructor
#include <iostream>
using namespace std;
class Animal {
public:
Animal(string name) {
cout << "Animal constructed: " << name << endl;
}
};
class Dog : public Animal {
public:
Dog(string name) : Animal(name) {
cout << "Dog constructed" << endl;
}
};
int main() {
Dog d("Rex");
}
Step by Step Execution
Consider this example:
#include <iostream>
using namespace std;
class Base {
public:
Base(int x) {
cout << "Base: " << x << endl;
}
};
class Derived : public Base {
public:
Derived(int x, int y) : Base(x) {
cout << "Derived: " << y << endl;
}
};
int main() {
Derived obj(10, 20);
}
Step-by-step
main()createsobjwithDerived obj(10, 20);- C++ starts constructing a
Derivedobject. - Before entering the
Derivedconstructor body, it sees: Base(x)in the initializer list.
Real World Use Cases
Base constructor calls appear often in real C++ programs.
1. Initializing shared state in a framework base class
A base class may store common data such as an ID, name, file path, or configuration.
class Widget {
public:
Widget(string id) {}
};
class Button : public Widget {
public:
Button(string id) : Widget(id) {}
};
2. Resource management
A base class may open or manage a resource during construction.
class FileOwner {
public:
FileOwner(const string& path) {}
};
class LogFile : public FileOwner {
public:
LogFile(const string& path) : FileOwner(path) {}
};
3. Reusing validation or setup logic
A base class can ensure core invariants are established before the derived class adds extra behavior.
4. GUI, game, and engine code
Frameworks often have base classes like Entity, , or . Derived classes pass values up to the base constructor so the framework can initialize common behavior first.
Real Codebase Usage
In real codebases, developers usually combine base constructor calls with a few common patterns.
Guarding object validity early
The base class often establishes state that every derived object must have.
class Connection {
public:
Connection(string host) {
// validate or store host
}
};
class SecureConnection : public Connection {
public:
SecureConnection(string host) : Connection(host) {}
};
Forwarding constructor arguments
A common pattern is to receive arguments in the derived constructor and pass some or all of them to the base constructor.
class Person {
public:
Person(string name) {}
};
class Employee : public Person {
public:
Employee(string name, int id) : Person(name), employeeId(id) {}
private:
int employeeId;
};
Initializing members and base classes together
Initializer lists are used not just for base classes, but also for members.
Common Mistakes
1. Trying to call the base constructor inside the constructor body
This is wrong:
class Base {
public:
Base(int x) {}
};
class Derived : public Base {
public:
Derived(int x) {
Base(x); // does not initialize the base subobject
}
};
Why it is wrong:
- The base subobject has already been constructed before the body starts.
Base(x);inside the body creates a temporary object instead of initializing the inherited base part.
Correct version:
class Derived : public Base {
public:
Derived(int x) : Base(x) {}
};
2. Forgetting that C++ uses the default base constructor automatically
Broken code:
class Base {
public:
Base( x) {}
};
: Base {
:
() {}
};
Comparisons
C++ vs Java base constructor rules
| Topic | C++ | Java |
|---|---|---|
| Where base constructor is specified | In the initializer list | In the constructor using super(...) |
| Must base construction happen before derived body? | Yes | Yes |
| Automatic call if omitted | Yes, tries the base default constructor | Yes, inserts super() |
| Error if no default constructor exists | Yes | Yes |
| Can you call base constructor in body? | No | No |
| Syntax style | Derived() : Base(args) {} | Derived() { super(args); } |
Initializer list vs constructor body
Cheat Sheet
Quick rules
- A base class is constructed before the derived class body runs.
- Use the initializer list to choose the base constructor.
- Syntax:
Derived(args) : Base(baseArgs) {}
- If you omit the base constructor, C++ tries to call the base default constructor.
- If no default constructor exists, compilation fails.
- You cannot initialize the base class from inside the constructor body.
- Base classes are constructed before members.
- With multiple base classes, construction order follows the inheritance declaration order, not the initializer list order.
Common pattern
class Base {
public:
Base(int x) {}
};
class Derived : public Base {
public:
Derived(int x, int y) : Base(x), value(y) {}
private:
int value;
};
Wrong pattern
Derived(int x) {
Base(x); // wrong: temporary object, not base initialization
}
FAQ
What happens if I do not call the base class constructor in C++?
C++ automatically tries to call the base class default constructor. If the base class has no default constructor, compilation fails.
Can I call the base constructor from inside the derived constructor body?
No. By the time the body runs, the base part has already been constructed. You must use the initializer list.
Is Base(x) inside the initializer list a normal function call?
No. It is constructor initialization syntax, not a regular function call.
In what order are constructors called in inheritance?
Base class constructors run first, then member objects, then the derived constructor body.
What if there are multiple base classes?
They are constructed in the order they appear in the class inheritance declaration, not the order written in the initializer list.
Is C++ behavior similar to Java super()?
Yes in purpose, but the syntax is different. C++ uses the initializer list, while Java uses super(...) inside the constructor.
What if the base constructor throws an exception?
The derived constructor body will not run, because the object was not fully constructed.
Do I always need to write the base constructor explicitly?
No. Only when you want a specific base constructor or when the base has no usable default constructor.
Mini Project
Description
Build a small inheritance example that models a user account system. The base class should store a username, and the derived class should add a permission level. This demonstrates how a derived class passes required data to the base constructor during object creation.
Goal
Create a derived object that correctly initializes both the base class and its own member data using a constructor initializer list.
Requirements
- Create a base class named
Userwith a constructor that requires a username. - Create a derived class named
AdminUserthat inherits fromUser. - Pass the username from
AdminUserto theUserconstructor. - Store a permission level inside
AdminUser. - Print both the username and permission level to confirm construction worked.
Keep learning
Related questions
Basic Rules and Idioms for Operator Overloading in C++
Learn the core rules, syntax, and common idioms for operator overloading in C++, including member vs non-member operators.
C++ Casts Explained: C-Style Cast vs static_cast vs dynamic_cast
Learn the difference between C-style casts, static_cast, and dynamic_cast in C++ with clear examples, safety rules, and real usage tips.
C++ Functors Explained: What They Are and When to Use Them
Learn what C++ functors are, how operator() works, and when function objects are useful in STL algorithms and real codebases.