I have the following three class defined in a .h file:
class Base
{ // number of pure virtual functions };
class Derived1 : public Base
{ // number of pure virtual functions };
class Derived2 : public Base
{ // number of pure virtual functions };
I want users of this header file to only subclass Derived1 or Derived2. I want to prevent users from subclass'ing Base. I "could" have used the keyword "final" for class Base, but that would prevent me from subclassing in my header file. I need to have all the above classes in the header file as a user needs to provide definitions of methods in Base and DerivedX classes.
I am thinking of something like limiting the scope of inheritance to within a header file (similar to a static variable). Any suggestions or ideas would be greatly appreciated.
You could make the Base
constructor private and have those two classes friends, e.g.
#include <iostream>
class Base
{
private:
Base() {}
friend class Derived1;
friend class Derived2;
};
class Derived1 : public Base
{
};
class Derived2 : public Base
{
};
int main() {
Derived1 obj;
Base obj2; // Error
return 0;
}
http://ideone.com/NUWad0
Also notice: copy/move constructor of base class should probably also be private. I'm not adding the code to focus on the main proposal but you should think about it too.
Edit with regard to friend constructors.
First off: you cannot reference the members of an incomplete type before its definition is seen by the compiler (it works as a one-time pass and there might be some overload resolution involved). This means the following won't work:
class Derived1;
class Derived2;
class Base
{
private:
Base() {}
friend Derived1::Derived1(); // Error - incomplete type 'Derived1' in nested name specifier
};
class Derived1 : public Base
{
public:
Derived1() {};
};
...
and you cannot forward declare a base class (you wouldn't know how much space to allocate for a derived object):
class Base;
class Derived1 : public Base // Error: base class has incomplete type
{
public:
Derived1() {};
};
class Base
{
private:
Base() {}
friend Derived1::Derived1();
};
...
therefore in your specific case you'd better off with a friend class access unless you want to modify something in your design.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With