Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing pure virtual functions with multiple inheritance

Suppose there is this interface:

class A{  
 public:  
  virtual foo()=0;  
};

And a class B which implements this interface:

class B:public A{    
 public:   
  virtual foo(){} //Foo implemented by B   
}

Finally, a class C which has classes A and B as base classes:

Class C : public A, public B {
};

My question is, there is a way to tell the compiler that the implementation for foo is the one from class B without doing an explicit call to B::foo()?

like image 607
Daniel Saad Avatar asked Dec 26 '12 17:12

Daniel Saad


People also ask

Can multiple inheritance have virtual function?

Virtual inheritance is used when we are dealing with multiple inheritance but want to prevent multiple instances of same class appearing in inheritance hierarchy. From above example we can see that “A” is inherited two times in D means an object of class “D” will contain two attributes of “a” (D::C::a and D::B::a).

Can pure virtual function have implementation?

This was a rather long-winded way of calling out a weird corner case in C++ that most people don't even realize exists: A pure virtual function can have an implementation.

Are pure virtual functions inherited?

Virtual member functions are inherited. A class derived from an abstract base class will also be abstract unless you override each pure virtual function in the derived class. The compiler will not allow the declaration of object d because D2 is an abstract class; it inherited the pure virtual function f() from AB .

What is pure virtual function how it can be implemented?

Pure Virtual Functions and Abstract Classes in C++It is declared by assigning 0 in the declaration. An abstract class is a class in C++ which have at least one pure virtual function. Abstract class can have normal functions and variables along with a pure virtual function.


1 Answers

As @BenVoigt pointed out in the comments, the below answer only works due to a bug in g++ (meaning it isn't guaranteed to keep working, and it definitely isn't portable). Thus, although it may do what you want if you use a particular (buggy) compiler, it isn't an option you should use.

Do use virtual inheritance though.


This isn't exactly the scenario that the code in the question implies, but the sentence

My question is, there is a way to tell the compiler that the implementation for foo is the one from class B without doing an explicit call to B::foo()?

seems to be asking for syntax to distinguish between multiple base versions of a function without using the :: qualifier.

You can do this with the using directive:

#include <iostream>
class A {
public:
A(){}
virtual void foo(){std::cout<<"A func";}
};

class B: virtual public A {
  public:
  B(){}
  virtual void foo(){std::cout<<"B func";}
};
class C:virtual public A, virtual public B {
    public:
    C(){}
    using A::foo; // tells the compiler which version to use
                   // could also say using B::foo, though this is unnecessary
};

int main() {
    C c;
    c.foo(); // prints "A func"
    return 0;
}

Of course, the code itself in the question doesn't require this at all, as the other answers have pointed out.

like image 169
tmpearce Avatar answered Sep 28 '22 11:09

tmpearce