Question
In C++, how can I call a function defined in a base class from a function in a derived class?
For example, suppose I have a class named Parent and a class named Child that inherits from Parent. Both classes define a print() function. Inside the Child::print() function, I want to call the Parent::print() function as well.
What is the correct way to do this?
class Parent {
public:
void print() {
// parent behavior
}
};
class Child : public Parent {
public:
void print() {
// call Parent::print() here
}
};
Short Answer
By the end of this page, you will understand how to call a base class function from a derived class in C++, why scope resolution is used for this, how overriding works, and how this pattern appears in real codebases.
Concept
In C++, a derived class inherits members from its base class. If the derived class defines a function with the same name and signature as one in the base class, the derived version hides or overrides the base version, depending on whether the base function is virtual.
When you are inside the derived class and want to explicitly call the base class version, you use the scope resolution operator :: with the base class name:
Parent::print();
This tells C++: "Use the print() function that belongs to Parent, not the one in Child."
This matters because derived classes often want to extend base behavior rather than completely replace it. For example:
- log something before calling the original implementation
- validate input, then reuse base logic
- add UI-specific behavior on top of shared functionality
- preserve setup/cleanup work done by the base class
This is a fundamental part of object-oriented programming in C++: reusing inherited behavior while still customizing it.
Mental Model
Think of a base class as a standard recipe, and a derived class as a modified version of that recipe.
Parent::print()is the original recipe step.Child::print()is your customized step.- If you still want to include the original step, you explicitly say: "Run the parent version first" or "Run the parent version too."
In code, that looks like:
Parent::print();
So the derived class is not forced to choose between only parent or only child behavior. It can combine both.
Syntax and Examples
The basic syntax is:
BaseClassName::functionName();
Example 1: Calling the parent version
#include <iostream>
using namespace std;
class Parent {
public:
void print() {
cout << "Printing from Parent" << endl;
}
};
class Child : public Parent {
public:
void print() {
Parent::print();
cout << "Printing from Child" << endl;
}
};
int main() {
Child c;
c.print();
}
Output:
Printing from Parent
Printing from Child
Here, Child::print() first calls Parent::print(), then adds its own behavior.
Example 2: Calling the parent version after child logic
#include <iostream>
using namespace std;
class Parent {
public:
void print() {
cout << "Base work" << endl;
}
};
class Child : public Parent {
public:
void print() {
cout << "Extra child work" << endl;
Parent::print();
}
};
This is also valid. The order depends on the behavior you want.
Example 3: With virtual
#include <iostream>
using namespace std;
class Parent {
public:
virtual void print() {
cout << "Parent print" << endl;
}
};
class Child : public Parent {
public:
void print() override {
Parent::print();
cout << "Child print" << endl;
}
};
Using virtual and override is recommended when you intend polymorphic behavior. It makes your design clearer and safer.
Step by Step Execution
Consider this example:
#include <iostream>
using namespace std;
class Parent {
public:
void print() {
cout << "Parent::print()" << endl;
}
};
class Child : public Parent {
public:
void print() {
cout << "Start Child::print()" << endl;
Parent::print();
cout << "End Child::print()" << endl;
}
};
int main() {
Child c;
c.print();
}
Program flow:
Child c;creates an object of typeChild.c.print();callsChild::print()becausecis aChildobject.- The line
cout << "Start Child::print()"runs first. Parent::print();explicitly calls the base class function.- That prints
Parent::print(). - Control returns to
Child::print(). - The final line prints
End Child::print().
Output:
Start Child::print()
Parent::print()
End Child::print()
The key idea is that Parent::print() is not called automatically just because both classes have a print() function. You must call it explicitly if you want it to run.
Real World Use Cases
Calling a base class function from a derived class is common in real programs when you want to reuse shared behavior.
Common scenarios
- GUI frameworks: a custom widget overrides a draw or render function, but still calls the base drawing logic.
- Game development: a derived game object updates custom behavior and then calls a base
update()method. - Logging and monitoring: a child class adds logging before or after base processing.
- Validation layers: a derived class performs extra checks, then uses the base implementation.
- Network or API handlers: a subclass handles special cases but still wants the common request-processing logic.
Example
class RequestHandler {
public:
virtual void handle() {
// common request processing
}
};
class AuthenticatedHandler : public RequestHandler {
public:
void handle() override {
// check authentication
RequestHandler::handle();
// additional authenticated logic
}
};
This pattern helps avoid duplicated code and keeps shared behavior in one place.
Real Codebase Usage
In real C++ codebases, developers often use base-class calls as part of structured extension.
Common patterns
1. Extend, do not replace
A derived method adds behavior while preserving the base logic.
void Child::print() {
Parent::print();
// extra behavior
}
2. Guard clause before base call
The derived class may stop early if conditions are not valid.
void Child::print() {
if (!isReady) {
return;
}
Parent::print();
}
3. Pre-processing and post-processing
void Child::print() {
prepare();
Parent::print();
cleanup();
}
4. Polymorphic design with virtual and override
class Parent {
public:
virtual void print();
};
class Child : public Parent {
public:
void print() override;
};
This helps catch mistakes at compile time and makes inheritance relationships clearer.
5. Constructor usage
Although this page focuses on regular member functions, base constructors are also commonly called from derived classes:
class Parent {
public:
Parent(int x) {}
};
class Child : public Parent {
public:
Child(int x) : Parent(x) {}
};
That is a related but separate syntax from calling a base member function.
Common Mistakes
Here are some beginner mistakes to watch for.
1. Accidentally calling the child version again
This causes recursion.
class Child : public Parent {
public:
void print() {
print(); // wrong: calls Child::print() again
}
};
This keeps calling itself until the program crashes.
Use this instead:
Parent::print();
2. Forgetting the class name
Inside the child, writing only print(); calls the current class version if one exists.
void print() {
print(); // wrong
}
Be explicit with Parent::print();.
3. Not using virtual when polymorphism is intended
class Parent {
public:
void print() {}
};
If you later call print() through a Parent* or Parent&, the child version will not be used unless the function is virtual.
Better:
class Parent {
public:
virtual void print() {}
};
4. Forgetting override
Without override, you may accidentally create a different function signature.
class Parent {
public:
virtual void print() {}
};
class Child : public Parent {
public:
void print(int x) {} // not overriding
};
Use:
void print() override {}
5. Trying to call a private base function
If the base function is private, the derived class cannot call it directly.
class Parent {
private:
void print() {}
};
Use protected or public if derived classes should access it.
Comparisons
| Concept | Meaning | Typical Use |
|---|---|---|
Parent::print() | Explicitly call the base class version | Reuse base behavior from derived code |
print() inside Child | Calls the current class version | Normal method call inside the same class |
virtual | Enables runtime dispatch | Polymorphism through base pointers/references |
override | Confirms a derived function overrides a base virtual function | Safer inheritance code |
print() vs Parent::print()
void print() {
print(); // calls Child::print() again
Parent::print(); // calls Parent version
}
Hiding vs overriding
| Situation | Result |
|---|---|
Same function name, no virtual | Derived function hides base function |
Base function is virtual and derived matches signature | Derived function overrides base function |
When to use virtual
Use virtual when objects may be used through base class pointers or references:
Parent* p = new Child();
p->print();
Without virtual, this calls Parent::print().
With virtual, it calls Child::print().
Cheat Sheet
Quick syntax
BaseClassName::functionName();
Example:
class Parent {
public:
void print() {}
};
class Child : public Parent {
public:
void print() {
Parent::print();
}
};
Key rules
- A derived class can call a base class function with
BaseClassName::functionName(). - If the derived class has a function with the same name, calling only
functionName()may call the derived version. - Use
virtualin the base class if you want polymorphic dispatch. - Use
overridein the derived class to confirm correct overriding. - The base function must be accessible (
publicorprotected).
Common safe pattern
class Parent {
public:
virtual void print() {
// base behavior
}
};
class Child : public Parent {
public:
void print() override {
Parent::print();
// extra child behavior
}
};
Danger signs
print(); // may call the child version again
Access notes
public: callable from anywhere allowed by the objectprotected: callable inside derived classesprivate: not callable directly from derived classes
FAQ
How do I call a parent class method in C++?
Use the base class name followed by the scope resolution operator:
Parent::print();
Can I call the base class function from an overridden function?
Yes. This is a common pattern when you want to keep the original behavior and add new behavior in the derived class.
Why does print(); call the child version instead of the parent version?
Because unqualified calls inside the derived class resolve to the current class function when one exists. Use Parent::print(); to explicitly choose the base version.
Do I need virtual to call the parent function?
No. You can explicitly call Parent::print(); without virtual. virtual is for polymorphic dispatch through base pointers and references.
Should I use override in the child class?
Yes, if the base function is virtual. It helps the compiler catch mistakes.
Can a derived class call a private base function?
No. A private base member is not directly accessible in the derived class.
What if the parent and child functions have different parameters?
Then they are different overloads or separate functions. To override, the signature must match exactly.
Is this the same as calling a base constructor?
No. Base constructors are called using the derived constructor's initializer list, not with Parent::functionName();.
Mini Project
Description
Build a small C++ example that models a reporting system. A base class will print general report information, and a derived class will add extra details while still calling the base implementation. This demonstrates how inherited behavior can be reused instead of duplicated.
Goal
Create a derived class that extends a base class method by calling the base version and then adding its own output.
Requirements
- Create a base class named
Reportwith aprint()function. - Create a derived class named
SalesReportthat also definesprint(). - Inside
SalesReport::print(), callReport::print(). - Print additional sales-specific information from the derived class.
- In
main(), create aSalesReportobject and callprint().
Keep learning
Related questions
Advantages of Brace Initialization in C++
Learn why C++ brace initialization is often clearer and safer than other object initialization styles, with examples and common pitfalls.
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++ Aggregates, Trivial Types, Trivially Copyable Types, and PODs Explained
Learn what aggregates, trivial types, trivially copyable types, and PODs mean in C++, how they differ, and why they matter.