Question

Recently I have attended one C++ technical interview: during that interviewer asked me one question which I was not able to answer: Even I tried on internet and some forums however unable to get the answer, Please see the code snippet below:

using namespace std;

class Base1
{
    public:
    Base1() 
    {
        cout << "Base1 constructor..." << endl;
    }

    ~Base1() 
    {
        cout << "Base1 Destructor..." << endl;
    }
};  

class Base2
{
public:
    Base2() 
    {
        cout << "Base2 constructor..." << endl;
    }

    ~Base2() 
    {
      cout << "Base2 Destructor..." << endl;  
    }
};

class Derived : public Base1, public Base2 
{
public:
  Derived()
  {
      cout << "Derived constructor...."  << endl;
  }
  ~Derived()
  {
      cout << "Derived Destructor..." << endl;
   }
};


int main()
{
   cout << "Hello World" << endl; 
   Base1 b1; Base2 b2;
   Derived d1;

   return 0;
}

Description: There are two base classes named Base1 and Base2 and one derived class named Derived. Derived is multiple inherited from Base1 and Base2.

The question:I want Derived should be inherited only from one class not from both. If developer will try to inherit from both classes: then the error should generate: let me summarize it:

  • Scenerio 1: class Derived : public Base1 // Ok.---> No Error
  • Scenerio 2: class Derived : public Base2 // Ok.---> No Error
  • Scenerio 3: class Derived : public Base1, public Base2 // Error or exception or anything. Not able to inherit.

Note: Can you answer this problem: I am really not sure whether this is feasible or not. And one more thing: this is not a diamond problem.

Thanks.

Was it helpful?

Solution

Declare a pure virtual function in both bases that have a different return type:

class B1 {
   virtual void a() = 0;
};

class B2 {
   virtual int a() = 0; // note the different return type
};

It's impossible to inherit from both.

class D : public B1, public B2 {
public:
    // virtual void a() {} // can't implement void a() when int a() is declared and vice versa
    virtual int  a() {}
};

int main(void) {
    D d; // produces C2555 error
    return 0;
}

This error is produced:

  • error C2555: 'D::a': overriding virtual function return type differs and is not covariant from 'B1::a'
  • see declaration of 'B1::a'

OTHER TIPS

You can do this with C++11, look:

#include <type_traits>
struct Base1 {}; 
struct Base2 {}; 

struct Derived 
   : public Base1
  , public Base2
{ 
  Derived() 
  { 
     static_assert( !(std::is_base_of< Base1, Derived >::value && std::is_base_of< Base2, Derived >:: value), "You cannot inherit from both Base1 and Base2" ); 
  } 
}; 



int main() { Derived d; return 0; }

It works and compiles only if you inherit from Base1 or from Base2. If you try to inherit from both, it doesn't compile. If you want a run-time error, instead of a compile time error, you could even use the same method to check that. Try to play with this snippet.

A run time check:

#include <iostream>
#include <stdexcept>
#include <typeinfo>

class B1 {
    protected:
    template <typename D>
    B1(D* d) {
        // The paranoid 'is_same' is preventing the cast (B1*)this in the derived constructor.
        if((void*)this != (void*)d || std::is_same< B1, D >::value)
            throw std::logic_error("Multiple Inheritance [1]");
    }

    int data;
};

class B2 {
    protected:
    template <typename D>
    B2(D* d) {
        // The paranoid 'is_same' is preventing the cast (B2*)this in the derived constructor.
        if((void*)this != (void*)d || std::is_same< B2, D >::value)
            throw std::logic_error("Multiple Inheritance [2]");
    }

    int data;
};


struct D : public B1, public B2 {
    D()
    :   B1(this), B2(this)
    {}
};

int main() {
    D d;
}

Note: This does not work if classes are empty. Not as good as the excellent idea of @egur. It has the benefit of not introducing virtual functions, though.

Use the method suggested by Lai Yu-Hsuan but give Base0 a pure virtual function that has to be overridden by Base1 and Base2. The compiler should complain about ambiguous function if you try to inherit from both Base1 and Base2. Edit: This is not the correct answer as pointed by Mike below

The only way I can figure out is to force this situation to be a diamond problem.

class Base1 : public Base0
class Base2 : public Base0

Then if the user tries to inherit from both Base1 and Base2 the compiler will complain.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top