Is it possible to prevent multiple inheritance of certain base classes at compile time?

What I want to do is to develop two different base classes that should not be inherited together in the same derived class. Is there a way I can provide this at compile time?

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? 

I know the documentation is a good idea, just wondering if this is possible.

+7
source share
2 answers

You set up some kind of connection between Base1 and Base2 so that both of them cannot be received.

You can make them both from Base0, and in this case, if you get Base1 and Base2, you will get a multiple inheritance diamond in order to get a compiler error, assuming that you are not using virtual inheritance and you are not allowing duplication.

This may solve your problem, but I doubt why you are trying to do it.

(Base0 should not be a completely empty class, as there must be something ambiguous there to make the compiler complain. And, of course, you could decide that it doesnโ€™t completely stop you from extracting what it will generate from them required compiler error if you do this by mistake).

An example could be:

 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 }; 
+8
source

An interesting problem. I found a solution that works for Microsoft (R) C / C ++ Compiler Optimization version 18.00.31101 for 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; } 
0
source

All Articles