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
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.
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
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
{
:
{}
};
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 {
();
Parent::();
}
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
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?
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.