0

I'd like for an inherited class B to overload a member function func() of its base class, A. I know that when accessed by an object of B, then B::func() will be called and A::func() will be hidden unless explicitly referenced via A:: or using.

Suppose now that A has another method another_func(), which calls func(). Assuming all members and inheritance are public, of course B will inherit another_func().

Now if I call func() from B::another_func(), I want B::func() to be called, but when I try it, A::func() is called. Is there a way to achieve the behaviour I'm looking for, for the given code structure?

I found this, but it's not quite the same thing.

The answer here is helpful in general, but doesn't really address my question.

In case the wording was confusing, here it is in code form:

Header:

#include <iostream>

class A
{
public:

    void func() { std::cout << "Called A::func()" << std::endl; };
    void another_func() { func(); };

};

class B: public A
{
public:

    void func() { std::cout << "Called B::func()" << std::endl; };

};

Source:

int main(int argc, char** argv)
{
    B B_obj;
    B_obj.func();
    B_obj.another_func(); // I want this to call B::func?
    return 0;
}

The output of this code is:

Called B::func()                                                                                                              
Called A::func()

The ouput I want is:

Called B::func()                                                                                                              
Called B::func()

The obvious answer is to directly do B::func() instead of B::another_func(), but my actual situation is more complicated, and it would be very useful for me to be able to do something similar to the above.

Edit Based on this, I tried making A::func a virtual method, and it works the way I want. However, I have also read that virtual functions are much more expensive to call. Is there a better way?

JeJo
  • 30,635
  • 6
  • 49
  • 88
josh_eime
  • 39
  • 5

1 Answers1

4

virtual is the only way for this(for now). You defined class A without any reference to possible derived classes of it. It's on class B you should define if a function from class A should changed and replace its own version of that function. The only way is make class A allow its derived classes to change a method. And it's by making that method virtual.

#include <iostream>

class A
{
public:

    virtual void func() { std::cout << "Called A::func()" << std::endl; };
    void another_func() { func(); };

};

class B: public A
{
public:    
    void func() override { std::cout << "Called B::func()" << std::endl; };    
};

If it happens that you don't want to use virtual due to it's slowness. Imagine implementing this kind of behavior from scratch in assembly/machine-language. Or even redesign the architecture. You will end up making the same behavior with what's virtual is doing now. Provide a member pointer to a function that might be changed by derived classes.


Edit:

I have also read that virtual functions are much more expensive to call.

No virtual methods are quite fast.
From Bjarne Stroustrup's official website:

In my experience, the efficiency reason is usually misplaced fear. In C++, virtual function calls are so fast that their real-world use for a class designed with virtual functions does not to produce measurable run-time overheads compared to alternative solutions using ordinary function calls. Note that the virtual function call mechanism is typically used only when calling through a pointer or a reference.

acegs
  • 2,621
  • 1
  • 22
  • 31