C++: inherited classes have pure virtual functions with identical names. How can I override them separately in my base class?

Viewed 112

The following code illustrates my question:

namespace foo1
{
    class bar1
    {
        public:
        virtual void fn() = 0; //this must remain pure virtual
    };
};

namespace foo2
{
    class bar2
    {
        public:
        virtual void fn() = 0; //this must remain pure virtual
    };
};

class bar3: public foo1::bar1, public foo2::bar2
{
    public:

    //can i separately override virtual functions from inherited 
    //classes that have the same name?

    void foo1::bar1::fn() override {std::cout << "bar1";} //error
    void foo2::bar2::fn() override {std::cout << "bar2";} //error
};

int main()
{
    bar3* obj = new bar3();

    ((foo1::bar1*)obj)->fn(); //i want this to print "bar1"
    ((foo2::bar2*)obj)->fn(); //and this to print "bar2"
}

Basically I want to be able to override inherited functions, such that by simply casting my base class object to one of the inherited classes, I can call the different functions even though they have the same name. Is this possible?

2 Answers

Sure.

struct foo1bar1helper:public foo1::bar1{
  void fn()final{foo1bar1fn();}
  virtual void foo1bar1fn()=0;
};

now bar3 just inherits from this instead of bar1 and overrides foo1bar1fn(),

Do the same with bar2.

You can also use CRTP to dispatch and do away with the extra vtable lookup;

template<class D>
struct foo1bar1helper:public foo1::bar1{
  void fn()final{static_cast<D*>(this)->foo1bar1fn();}
};

template<class D>
struct foo2bar2helper:public foo2::bar2{
  void fn()final{static_cast<D*>(this)->foo2bar2fn();}
};

class bar3:
  public foo1bar1helper<bar3>,
  public foo2bar2helper<bar3>
{
public:
  void foo1bar1fn(){}
  void foo2bar2fn(){}
};

You can not do that. When you do foo1::bar1::fn(), compiler thinks that you are defining function fn of 'bar1' of 'foo1' namespace in class bar3. Hence compiler is throwing below error.

error: cannot define member function ‘foo1::bar1::fn’ within ‘bar3’

But when you extend from an abstract class, you need to give the definition of the function (which should be part of your derived class) in derived class.

Related