489

How do I call the parent function from a derived class using C++? For example, I have a class called parent, and a class called child which is derived from parent. Within each class there is a print 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?


  • All the above solutions are assuming that your print function is a static method. Is this the case? If the method is not static then the above solutions are not relevant. - hhafez
  • hhafez, you are mistaken the base::function() syntax looks like static method call syntax but it works for instance methods in this context. - Motti
  • I wouldn't use the MSVC __super since it's platform specific. Although your code may not run on any other platform, I'd use the other suggestions since they do it as the language intended. - Teaser
  • Possible duplicate of Can I call a base class's virtual function if I'm overriding it? - Archmede

6 답변


629

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
};


  • Why would you like to inherit from the same class twice ? - Paul Brewczynski
  • @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. - Emilio Garavaglia
  • I 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. - Maxim Lavrov
  • On 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. - Mathai
  • @Mathai And that is why you aren't supposed to use using namespace std. - JAB

166

Given parent class named Parent and child class named Child, you can do something like this:

class Parent {
public:
    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.


  • Why does this anwer has so many upvotes? I don't see how this can be done in C++. - ancajic
  • @ancajic: Using the names of classes from the question, parent is the actual name of the parent class. If the parent class were called widget, then you would call widget::print(x);. - Greg Hewgill
  • Of 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
  • @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. - iheanyi
  • @iheanyi Sounds interesting, but sorry, I'm not grasping it yet. Is foo() here analogous to print() or a separate function? And do you mean by using private inheritance to hide details inherited from the base, and providing public shadowing functions for things you do want to expose? - underscore_d

28

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();
}


20

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)
   }
};


  • Eh, I'd prefer typdefing the parent as something like super. - Thomas Eding
  • I 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. - Andrey
  • I'd rather discourage anyone from using it, as it severely hinders portability of the code. - Erbureth
  • I 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. - Gabriel
  • "Developers should know their compiler" this reasoning, and the inclusion of non standard features, is what led to IE6... - Ring Ø

3

If access modifier of base class member function is protected OR public, you can do call member function of base class from derived class. Call to the base class non-virtual and virtual member function from derived member function can be made. Please refer the program.

#include<iostream>
using namespace std;

class Parent
{
  protected:
    virtual void fun(int i)
    {
      cout<<"Parent::fun functionality write here"<<endl;
    }
    void fun1(int i)
    {
      cout<<"Parent::fun1 functionality write here"<<endl;
    }
    void fun2()
    {

      cout<<"Parent::fun3 functionality write here"<<endl;
    }

};

class Child:public Parent
{
  public:
    virtual void fun(int i)
    {
      cout<<"Child::fun partial functionality write here"<<endl;
      Parent::fun(++i);
      Parent::fun2();
    }
    void fun1(int i)
    {
      cout<<"Child::fun1 partial functionality write here"<<endl;
      Parent::fun1(++i);
    }

};
int main()
{
   Child d1;
   d1.fun(1);
   d1.fun1(2);
   return 0;
}

Output:

$ g++ base_function_call_from_derived.cpp
$ ./a.out 
Child::fun partial functionality write here
Parent::fun functionality write here
Parent::fun3 functionality write here
Child::fun1 partial functionality write here
Parent::fun1 functionality write here


-12

struct a{
 int x;

 struct son{
  a* _parent;
  void test(){
   _parent->x=1; //success
  }
 }_son;

 }_a;

int main(){
 _a._son._parent=&_a;
 _a._son.test();
}

Reference example.


  • Could 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. - Makyen
  • This 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. - Johannes Matokic

Linked


Related

Latest