Question

How to Call a Parent Class Function from a Derived Class in C++

cppoopinheritance

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.

Take Quiz

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:

  1. Child c; creates an object of type Child.
  2. c.print(); calls Child::print() because c is a Child object.
  3. The line cout << "Start Child::print()" runs first.
  4. Parent::print(); explicitly calls the base class function.
  5. That prints Parent::print().
  6. Control returns to Child::print().
  7. 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.

Take Quiz

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

ConceptMeaningTypical Use
Parent::print()Explicitly call the base class versionReuse base behavior from derived code
print() inside ChildCalls the current class versionNormal method call inside the same class
virtualEnables runtime dispatchPolymorphism through base pointers/references
overrideConfirms a derived function overrides a base virtual functionSafer inheritance code

print() vs Parent::print()

void print() {
    print();         // calls Child::print() again
    Parent::print(); // calls Parent version
}

Hiding vs overriding

SituationResult
Same function name, no virtualDerived function hides base function
Base function is virtual and derived matches signatureDerived 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().

Take Quiz

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 virtual in the base class if you want polymorphic dispatch.
  • Use override in the derived class to confirm correct overriding.
  • The base function must be accessible (public or protected).

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 object
  • protected: callable inside derived classes
  • private: 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();.

Take Quiz

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 Report with a print() function.
  • Create a derived class named SalesReport that also defines print().
  • Inside SalesReport::print(), call Report::print().
  • Print additional sales-specific information from the derived class.
  • In main(), create a SalesReport object and call print().
Take Quiz

Keep learning

Related questions

View more