What I am looking to do is develop two different base classes which should not be inherited together in the one derived class. Is there any way I can enforce this at compile tim
An interesting problem. I found a solution that works for Microsoft (R) C/C++ Optimizing Compiler 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;
}
You are setting up some kind of coupling between Base1 and Base2 in that they cannot both be derived from.
You could make them both derive from Base0 in which case if you derive from Base1 and Base2 you would get the multiple inheritance diamond so you would get a compiler error assuming you do not use virtual inheritance and you do not resolve the duplication.
That might solve your problem but I question why you are trying to do this.
(Base0 should not be a totally empty class as there has to be something there ambiguous to cause the compiler to complain. And of course you could resolve it so it won't totally prevent you deriving from both, just that it will generate the required compiler "error" if you do it by mistake).
An example might 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
};