Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The constructor function in a pure virtual class should be "protected" or "public"?

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.

like image 352
Wizmann Avatar asked Jun 04 '14 12:06

Wizmann


People also ask

Should a pure virtual class have a constructor?

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.

Should constructors be protected?

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.

Can pure virtual functions be private?

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++


2 Answers

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.

like image 188
Fred Foo Avatar answered Oct 12 '22 14:10

Fred Foo


Abstract classes and construction of such

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.


example snippet

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 ()`
}
like image 40
Filip Roséen - refp Avatar answered Oct 12 '22 15:10

Filip Roséen - refp