The following example is from the book "Inside C++ object model"
class Abstract_base {
public:
virtual ~Abstract_base () = 0;
virtual void interface () const = 0;
virtual const char* mumble () const
{
return _mumble;
}
protected:
char *_mumble;
};
The author says if I want to initialize _mumble
, the data member of the pure virtual base class, a "protected constructor" should be implemented.
But why protected? And why "public constructor" is not suitable for this class?
Thanks for your answers, and it would be perfect if there's an example.
A pure virtual class cannot be instantiated, so it doesn't make a difference if the constructor is public or protected. A public constructor is syntactically correct. However, making it protected will carry a stronger indication that the class cannot be instantiated.
Protecting a constructor prevents the users from creating the instance of the class, outside the package. During overriding, when a variable or method is protected, it can be overridden to other subclass using either a public or protected modifier only. Outer class and interface cannot be protected.
A virtual function can be private as C++ has access control, but not visibility control. As mentioned virtual functions can be overridden by the derived class but under all circumstances will only be called within the base class. Example: C++
It doesn't really matter, since you're not allowed to construct objects of the base class anyway. Making it protected
serves only as a reminder of the fact that the class is supposed to be a base class; it's only cosmetics/documentation.
Consider
struct Base {
virtual ~Base() = 0;
protected:
Base() { std::puts("Base constructor"); }
};
Base::~Base() { std::puts("Base destructor"); }
struct Derived : Base {};
int main()
{
//Base b; // compiler error
Derived d;
Base *b = new Derived();
delete b;
}
Removing the protected
doesn't change the meaning of the program in any way.
It doesn't matter if the constructor is public or protected, since an abstract class cannot be instantiated.
You must inherit from it in order to have it's constructor called, and since the Derived class calls the constructor of the abstract class it doesn't matter what protection level you choose, as long as the Derived class can access it.
One reason that one could possibly have for making it protected
is to serve as a reminder that the class must be constructed through inheritance, but honestly that should be clear enough when seeing that it has pure virtual member-functions.
struct B {
virtual void func () = 0;
virtual ~B () = 0 { };
};
B::~B () { }
struct D : B {
void func () override;
};
int main () {
B b; // will error, no matter if Bs ctor is 'public' or 'protected'
// due to pure virtual member-function
D d; // legal, D has overriden `void B::func ()`
}
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