是否可以在编译时阻止特定基类的多重继承?

时间:2012-01-06 07:35:58

标签: c++ multiple-inheritance

我要做的是开发两个不同的基类,这些基类不应该在一个派生类中一起继承。有什么办法可以在编译时强制执行吗?

class Base1 {};
class Base2 {};
class Derived1 : public Base1 {} // OK!
class Derived2 : public Base2, public Other {} // OK!
class Derived3 : public Base1, Base2 {} // Can I force the compiler to complain?

Derived1 d1; // OK!
Derived2 d2; // OK!
Derived3 d3; // Or can I force the compiler to complain here?

我知道documentation是一个好主意,只是想知道是否可能。

2 个答案:

答案 0 :(得分:8)

您正在Base1和Base2之间建立某种耦合,因为它们不能同时派生。

您可以使它们都从Base0派生,在这种情况下,如果您从Base1和Base2派生,您将获得多继承菱形,因此如果您不使用虚拟继承并且不解决重复,则会出现编译器错误。

这可能会解决您的问题,但我会质疑您为什么要这样做。

(Base0不应该是一个完全空的类,因为必须有一些不明确的东西导致编译器抱怨。当然你可以解决它,所以它不会完全阻止你从两者得到,只是它会如果误操作,则生成所需的编译器“错误”。

一个例子可能是:

class Base0 
{ 
  protected: 
    virtual ~Base0(){};
    virtual void abstractMethod() const = 0;
};

class Base1 : public Base0
{ 
   protected:
     virtual void abstractMethod() const;

   // rest of Base1
};

class Base2 : public Base0
{ 
   protected:
     virtual void abstractMethod() const;

   // rest of Base1
};

class Derived : public Base1, public Base2
{  
  // if I don't resolve abstractMethod it is ambiguous and the compiler will let me know
};

答案 1 :(得分:0)

一个有趣的问题。我找到了适用于x64的Microsoft(R)C / C ++优化编译器版本18.00.31101的解决方案:

#include <iostream>
#include <assert.h>
using namespace std;

class SuperBase {
public:
SuperBase():count(0) {
    cout << "SuperBase constructor..." << endl;
}
~SuperBase() {}
protected:
int count;
};
class Base1:virtual SuperBase
{
public:
Base1() 
{
    SuperBase::count++;
    assert(SuperBase::count==1);
    cout << "Base1 constructor..." << endl;
}

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

class Base2:virtual SuperBase
{
public:
Base2() 
{
    SuperBase::count++;
    assert(SuperBase::count==1);
    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;
   }
};

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



int main()
{
   cout << "Hello World" << endl; 
   Base1 b1; Base2 b2;
   Derived1 d1; 
   Derived2 d2;
   // Derived d; // - uncomment this line to get run-time error.

   return 0;
}