How to call a parent class function from derived class function?
Solution 1
I'll take the risk of stating the obvious: You call the function, if it's defined in the base class it's automatically available in the derived class (unless it's private
).
If there is a function with the same signature in the derived class you can disambiguate it by adding the base class's name followed by two colons base_class::foo(...)
. You should note that unlike Java and C#, C++ does not have a keyword for "the base class" (super
or base
) since C++ supports multiple inheritance which may lead to ambiguity.
class left {
public:
void foo();
};
class right {
public:
void foo();
};
class bottom : public left, public right {
public:
void foo()
{
//base::foo();// ambiguous
left::foo();
right::foo();
// and when foo() is not called for 'this':
bottom b;
b.left::foo(); // calls b.foo() from 'left'
b.right::foo(); // call b.foo() from 'right'
}
};
Incidentally, you can't derive directly from the same class twice since there will be no way to refer to one of the base classes over the other.
class bottom : public left, public left { // Illegal
};
Solution 2
Given a parent class named Parent
and a child class named Child
, you can do something like this:
class Parent {
public:
virtual void print(int x);
};
class Child : public Parent {
void print(int x) override;
};
void Parent::print(int x) {
// some default behavior
}
void Child::print(int x) {
// use Parent's print method; implicitly passes 'this' to Parent::print
Parent::print(x);
}
Note that Parent
is the class's actual name and not a keyword.
Solution 3
If your base class is called Base
, and your function is called FooBar()
you can call it directly using Base::FooBar()
void Base::FooBar()
{
printf("in Base\n");
}
void ChildOfBase::FooBar()
{
Base::FooBar();
}
Solution 4
In MSVC there is a Microsoft specific keyword for that: __super
MSDN: Allows you to explicitly state that you are calling a base-class implementation for a function that you are overriding.
// deriv_super.cpp
// compile with: /c
struct B1 {
void mf(int) {}
};
struct B2 {
void mf(short) {}
void mf(char) {}
};
struct D : B1, B2 {
void mf(short) {
__super::mf(1); // Calls B1::mf(int)
__super::mf('s'); // Calls B2::mf(char)
}
};
Solution 5
Call the parent method with the parent scope resolution operator.
Parent::method()
class Primate {
public:
void whatAmI(){
cout << "I am of Primate order";
}
};
class Human : public Primate{
public:
void whatAmI(){
cout << "I am of Human species";
}
void whatIsMyOrder(){
Primate::whatAmI(); // <-- SCOPE RESOLUTION OPERATOR
}
};
IaCoder
Updated on August 21, 2020Comments
-
IaCoder over 3 years
How do I call the parent function from a derived class using C++? For example, I have a class called
parent
, and a class calledchild
which is derived from parent. Within each class there is aprint
function. In the definition of the child's print function I would like to make a call to the parents print function. How would I go about doing this? -
Thomas Eding over 12 yearsEh, I'd prefer
typdef
ing the parent as something likesuper
. -
Andrey over 12 yearsI won't try to justify usage of
__super
; I mentioned it here as an alternative suggestion. Developers should know their compiler and understand pros and cons of its capabilities. -
Paul Brewczynski over 10 yearsWhy would you like to inherit from the same class twice ?
-
Emilio Garavaglia over 10 years@bluesm: in classic OOP it makes no much sense, but in generic programming
template<class A, class B> class C: public A, public B {};
can come to two types being the same for reasons depending on how your code is used (that makes A and B to be the same), may be two or three abstraction layer way from someone not aware of what you did. -
Erbureth about 10 yearsI'd rather discourage anyone from using it, as it severely hinders portability of the code.
-
Gabriel over 9 yearsI don't agree with Andrey: Developers should know the standard and should not need to bother with compiler features, if we consider writing software which is primarily compiler independent which I think is a good idea anyways because sooner or later in large projects multiple compilers are anyways used.
-
Maxim Lavrov over 9 yearsI think it's useful to add, that this will call parent class method even if it is not implemented directly in the parent class, but is implemented in one of the parent classes in the inheritance chain.
-
Makyen about 9 yearsCould you please edit in an explanation of why/how this code answers the question? Code-only answers are discouraged, because they are not as easy to learn from as code with an explanation. Without an explanation it takes considerably more time and effort to understand what was being done, the changes made to the code, or if the code is useful. The explanation is important both for people attempting to learn from the answer and those evaluating the answer to see if it is valid, or worth up voting.
-
martinkunev almost 9 yearswhat if the parent method uses this?
-
Motti almost 9 years@martinkunev, if the base class uses this then it works normally for regular methods and suppresses dynamic invocation for
virtual
methods. -
Johannes Matokic almost 9 yearsThis answer is about nested classes while the question was about derived classes (even though the words 'parent' and 'child' are a bit missleading) and therefore doesn't answer the question at all.
-
Mathai over 8 yearsOn a sidenote, it made me mad when i tried to put this in a cpp file. I had 'using namespace std'. 'left' is defined somewhere in that namespace. The example wouldn't compile - drove me crazy :) . Then I changed 'left' to 'Left'. Great example by the way.
-
JAB over 8 years@Mathai And that is why you aren't supposed to use
using namespace std
. -
underscore_d about 8 yearsOf course, this would only be useful if the base call were interspersed with other logic, otherwise there'd be no point in overriding the function, so maybe it's a little too to-the-point ;)
-
underscore_d about 8 years@ThomasEding I'd prefer neither, because C++ isn't Java, and it's not actually difficult to remember the name of the parent, plus it's required if using MI.
-
iheanyi about 8 years@underscore_d actually, its useful even if the base call was not interspersed with other logic. Let's say the parent class pretty much does everything you want, but exposes a method foo() you don't want users of child to use - either because foo() is meaningless in child or external callers to child will screw up what child is doing. So child may use parent::foo() in certain situations but provide an implementation of foo so that they hide parent's foo() from being called.
-
underscore_d about 8 years@iheanyi Sounds interesting, but sorry, I'm not grasping it yet. Is
foo()
here analogous toprint()
or a separate function? And do you mean by usingprivate
inheritance to hide details inherited from the base, and providingpublic
shadowing functions for things you do want to expose? -
iheanyi about 8 years@underscore_d Yes,
foo()
was analogous toprint()
. Let me go back to usingprint()
as I think it would make more sense in this context. Let's say someone created a class that carried out some set of operations on a particular datatype, exposed some accessors, and had aprint(obj&)
method. I need a new class that works onarray-of-obj
but everything else is the same. Composition results in a lot of duplicated code. Inheritance minimizes that, inprint(array-of-obj&)
loop callingprint(obj&)
, but don't want clients to callprint(obj&)
because doesn't make sense for them to do so -
iheanyi about 8 years@underscore_d This is predicated on the assumption that I can't refactor out the common parts of the original parent class or that doing so is incredibly costly. Private inheritance could work, but then you lose the public accessors which you were relying upon - and would thus, need to duplicate code.
-
Déjà vu almost 8 years"Developers should know their compiler" this reasoning, and the inclusion of non standard features, is what led to IE6...
-
TechNyquist over 7 years+1 for stating
You should note that unlike Java and C#, C++ does not have a keyword for "the base class"
. -
Patricio Rossi almost 7 yearsThis is a really bad idea, always try to avoid compiler specific features, or is really needed, use them inside #defines where yoou can handle the standard and non standard way.
-
Mitkins over 6 yearsI'm going to go against the comments and vote in favour of
__super
. It's nice and simple, and for the 99.9% of code which is SANE and doesn't use multiple inheritance, there's no problem with it. Explicitly specifying the base class has led to multiple hard to diagnose horrible bugs in our codebase throughout the years, where people end up accidentally going straight from Level3->Level1 and skipping the Level2 class in the middle; __super prevents this. Also portable code, that's a good point, however not all code cares about being portable -
Eljay over 6 yearsYou can add
typedef left super;
in your class if you want, then you can refer tosuper::foo();
. And since you cannot derive from the same class twice directly, you have to do it indirectlystruct left1 : left{}; struct left2 : left{}; class bottom : public left1, public left2 { ... };
but you are probably better off using composition rather than inheritance. -
pqnet about 6 years@OrionEdwards exactly for that code with only one inheritance
__super
doesn't add functionality, because you can name that class explicitly (or get a habit of doingtypedef Parent super
right after class declaration if you want to writesuper
): it's main purpose is to dispatch the function call to one of the two super classes when a method could be in one or another (i.e., mixin scenario). Sacrificing standard compliance may be justified if you explicitly need that functionality, not for lazyness. -
Alexey Andronov almost 6 years@OrionEdwards, well, always call Level2 methods from Level3 and you'll be fine
-
lsrawat over 5 yearswhat will happen if foo is virtual function in both base classes ?
-
M.Ionut about 4 yearsThank you for bringing some examples with
virtual
! -
sg_man almost 2 yearsThe answer mentions you have to use :: if the base/derived signatures match, but do "overloads" between base/derived need it to? e.g., Base::foo(int), Derived::foo(Bar). I think if you say this->foo(3) in a derived method, you'll get an error.
-
Motti almost 2 years@sg_man
this->foo(3)
is equivalent tofoo(3)
. It will go to the derived method. I also think you may be confusing "overload" and "override", see scaler.com/topics/….