How to call a parent class function from derived class function?
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
};
How do I call a parent class's method from a child class in Python?
Use the super()
function:
class Foo(Bar):
def baz(self, **kwargs):
return super().baz(**kwargs)
For Python < 3, you must explicitly opt in to using new-style classes and use:
class Foo(Bar):
def baz(self, arg):
return super(Foo, self).baz(arg)
Calling parent class member function from derived class
You just need to call
f1();
or if your derived class has its own f1 funciton (overriding) call
A::f1();
Calling appropriate parent class function from derived class function in multiple inheritance
This might be more of a design question. It is known that class C will have only one true parent (either A or B). And depending on which is the parent, I want that function to be called. Any alternative design suggestions are welcome.
class Base { };
class A : public Base { };
class B : public Base { };
class C
{
// common interface for all types of C
};
class C_A : public A, public C { };
class C_B : public B, public C { };
Now you can use C_A
, wherever a C
needs to behave as A
and C_B
analogously...
In above example, all virtual inheritances are removed, they are not needed as is. Depending on the use case, it might or might not be appropriate to let class C
itself inherit from Base. If so, let all of A
, B
and C
inherit virtually from Base. C_A
and C_B
, though, do not need to inherit virtually from their parents (there still will just be one Base
instance inherited due to the virtual inheritance of the base classes).
Call base class method from derived class object
You can always(*) refer to a base class's function by using a qualified-id:
#include <iostream>
class Base{
public:
void foo(){std::cout<<"base";}
};
class Derived : public Base
{
public:
void foo(){std::cout<<"derived";}
};
int main()
{
Derived bar;
//call Base::foo() from bar here?
bar.Base::foo(); // using a qualified-id
return 0;
}
[Also fixed some typos of the OP.]
(*) Access restrictions still apply, and base classes can be ambiguous.
If Base::foo
is not virtual
, then Derived::foo
does not override Base::foo
. Rather, Derived::foo
hides Base::foo
. The difference can be seen in the following example:
struct Base {
void foo() { std::cout << "Base::foo\n"; }
virtual void bar() { std::cout << "Base::bar\n"; }
};
struct Derived : Base {
void foo() { std::cout << "Derived::foo\n"; }
virtual void bar() { std::cout << "Derived::bar\n"; }
};
int main() {
Derived d;
Base* b = &d;
b->foo(); // calls Base::foo
b->bar(); // calls Derived::bar
}
(Derived::bar
is implicitly virtual even if you don't use the virtual
keyword, as long as it's signature is compatible to Base::bar
.)
A qualified-id is either of the form X :: Y
or just :: Y
. The part before the ::
specifies where we want to look up the identifier Y
. In the first form, we look up X
, then we look up Y
from within X
's context. In the second form, we look up Y
in the global namespace.
An unqualified-id does not contain a ::
, and therefore does not (itself) specify a context where to look up the name.
In an expression b->foo
, both b
and foo
are unqualified-ids. b
is looked up in the current context (which in the example above is the main
function). We find the local variable Base* b
. Because b->foo
has the form of a class member access, we look up foo
from the context of the type of b
(or rather *b
). So we look up foo
from the context of Base
. We will find the member function void foo()
declared inside Base
, which I'll refer to as Base::foo
.
For foo
, we're done now, and call Base::foo
.
For b->bar
, we first find Base::bar
, but it is declared virtual
. Because it is virtual
, we perform a virtual dispatch. This will call the final function overrider in the class hierarchy of the type of the object b
points to. Because b
points to an object of type Derived
, the final overrider is Derived::bar
.
When looking up the name foo
from Derived
's context, we will find Derived::foo
. This is why Derived::foo
is said to hide Base::foo
. Expressions such as d.foo()
or, inside a member function of Derived
, using simply foo()
or this->foo()
, will look up from the context of Derived
.
When using a qualified-id, we explicitly state the context of where to look up a name. The expression Base::foo
states that we want to look up the name foo
from the context of Base
(it can find functions that Base
inherited, for example). Additionally, it disables virtual dispatch.
Therefore, d.Base::foo()
will find Base::foo
and call it; d.Base::bar()
will find Base::bar
and call it.
Fun fact: Pure virtual functions can have an implementation. They cannot be called via virtual dispatch, because they need to be overridden. However, you can still call their implementation (if they have one) by using a qualified-id.
#include <iostream>
struct Base {
virtual void foo() = 0;
};
void Base::foo() { std::cout << "look ma, I'm pure virtual!\n"; }
struct Derived : Base {
virtual void foo() { std::cout << "Derived::foo\n"; }
};
int main() {
Derived d;
d.foo(); // calls Derived::foo
d.Base::foo(); // calls Base::foo
}
Note that access-specifiers both of class members and base classes have an influence on whether or not you can use a qualified-id to call a base class's function on an object of a derived type.
For example:
#include <iostream>
struct Base {
public:
void public_fun() { std::cout << "Base::public_fun\n"; }
private:
void private_fun() { std::cout << "Base::private_fun\n"; }
};
struct Public_derived : public Base {
public:
void public_fun() { std::cout << "Public_derived::public_fun\n"; }
void private_fun() { std::cout << "Public_derived::private_fun\n"; }
};
struct Private_derived : private Base {
public:
void public_fun() { std::cout << "Private_derived::public_fun\n"; }
void private_fun() { std::cout << "Private_derived::private_fun\n"; }
};
int main() {
Public_derived p;
p.public_fun(); // allowed, calls Public_derived::public_fun
p.private_fun(); // allowed, calls Public_derived::public_fun
p.Base::public_fun(); // allowed, calls Base::public_fun
p.Base::private_fun(); // NOT allowed, tries to name Base::public_fun
Private_derived r;
r.Base::public_fun(); // NOT allowed, tries to call Base::public_fun
r.Base::private_fun(); // NOT allowed, tries to name Base::private_fun
}
Accessibility is orthogonal to name lookup. So name hiding does not have an influence on it (you can leave out public_fun
and private_fun
in the derived classes and get the same behaviour and errors for the qualified-id calls).
The error in p.Base::private_fun()
is different from the error in r.Base::public_fun()
by the way: The first one already fails to refer to the name Base::private_fun
(because it's a private name). The second one fails to convert r
from Private_derived&
to Base&
for the this
-pointer (essentially). This is why the second one works from within Private_derived
or a friend of Private_derived
.
How to require child class method to call parent class method?
Non-Virtual Interface idiom has the base class define a public
non-virtual member function, and a private virtual member function that
is an override point for derived classes.
The public non-virtual member function acts as a public facing API.
The private virtual member function acts as a class hierarchy
facing API.
Separating those two concerns can be a handy technique especially
for larger projects, and for debugging purposes, and for ensuring
pre- and post- operations in the base class's public non-virtual
member function.
#include <iostream>
using std::cout;
namespace {
class A {
virtual void MyMethodImpl() const {
// Derived classes should override this virtual member function
// and add their extra steps there.
}
public:
virtual ~A() = default;
A() {}
void MyMethod() const {
cout << "A::MyMethod before steps.\n";
MyMethodImpl();
cout << "A::MyMethod after steps.\n";
}
};
class B : public A {
void MyMethodImpl() const override {
cout << "B::MyMethodImpl extra steps.\n";
}
public:
B() {}
};
} // anon
int main() {
B b;
b.MyMethod();
}
Call to non virtual function in derived class from base class (C++)
There ere 2 ways to archive the desired result:
Using virtual
Declaring base class functions as a virtual will make sure to call the most higher inheritance of the target functions by default. For example, in your case:
class A {
protected:
/**
* Declared also in the derived class, so as long the current object is the derived class,
* this function will be called from the derived class.
* [Enabled only due to the use of the `virtual` keyword].
*/
virtual void test() {
cout << "A test" << endl;
}
void f1() {
cout << "A f1" << endl;
test();
}
};
Using CRTP [Huge overhead to archive something you can archive using virtual]
template <class Derived> // Template param that will accept the derived class that inherit from this class.
class A {
protected:
virtual void test() const {
cout << "A test" << endl;
}
void f1() const {
cout << "A f1" << endl;
static_cast<Derived const&>(*this).test(); // Call test() function from the derived class.
}
};
class B: public A<B> { // inherit A that accepts template argument this derived class
// protected:
public: // Pay attention that now test should be public in the derived class in order to access it via the base class.
void test() const override {
cout << "B test" << endl;
}
//public:
void func() const {
cout << "B func" << endl;
f1();
}
};
Read more about CRTP.
Related Topics
Why Do C and C++ Compilers Allow Array Lengths in Function Signatures When They'Re Never Enforced
Pure Virtual Function With Implementation
What Is the Closest Thing Windows Has to Fork()
What Is the Usefulness of 'Enable_Shared_From_This'
How to Access Private Members from Outside the Class Without Using Friends
Why Are #Ifndef and #Define Used in C++ Header Files
How Exactly Does _Attribute_((Constructor)) Work
C++11 Does Not Deduce Type When Std::Function or Lambda Functions Are Involved
Are There Any Valid Use Cases to Use New and Delete, Raw Pointers or C-Style Arrays With Modern C++
Is There a Simple Way to Convert C++ Enum to String
How Does C++ Handle &&? (Short-Circuit Evaluation)