Можно ли предотвратить множественное наследование определенных базовых классов во время компиляции? - PullRequest
7 голосов
/ 06 января 2012

Я хочу разработать два разных базовых класса, которые не должны наследоваться вместе в одном производном классе. Могу ли я применить это во время компиляции?

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?

Я знаю, что документация хорошая идея, просто интересно, возможно ли это.

Ответы [ 2 ]

8 голосов
/ 06 января 2012

Вы настраиваете какую-то связь между Base1 и Base2, чтобы они не могли быть получены из обоих.

Вы можете сделать так, чтобы они оба были производными от Base0; в этом случае, если вы производите от Base1 и Base2, вы получите алмаз множественного наследования, так что вы получите ошибку компилятора, если вы не используете виртуальное наследование и не решаетеДублирование.

Это может решить вашу проблему, но я спрашиваю, почему вы пытаетесь это сделать.

(Base0 не должен быть полностью пустым классом, потому что должно быть что-то неоднозначное, чтобы вызватькомпилятор, чтобы жаловаться. И, конечно, вы могли бы разрешить его, чтобы он полностью не помешал вам наследовать оба, просто он сгенерирует требуемую «ошибку» компилятора, если вы сделаете это по ошибке).

Anпример может быть:

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
};
0 голосов
/ 23 мая 2015

интересная проблема. Я нашел решение, которое работает для оптимизирующего компилятора Microsoft (R) C / C ++ версии 18.00.31101 для x64:

#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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...