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

5

20

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.

Marcy answered 4/6, 2014 at 12:7 Comment(2)
Its pure-virtual. The only valid construction of such a thing is via derivation. Said derivation has access to a protected constructor. Nothing else (friends not withstanding) does. It doesn't matter in this case, but at least you know why.Demetricedemetris
It would be suitable indeed, but nobody except the derived class could call it anyway.Joniejonina
I
18

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.

Idell answered 4/6, 2014 at 12:12 Comment(2)
Why did you change the 'class' to 'struct'?Ostend
So he didn't have to write "public:" before the destructor I guess.Keely
N
7

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 ()`
}
Nysa answered 4/6, 2014 at 12:12 Comment(2)
I agree that it should be clear, however for clarity purpose it may still help (though then it becomes subjective, of course).Taking
About the "cannot be instantiated" part, the standard says: "no objects of an abstract class can be created except as subobjects of a class derived from it." More info at this answer to a related question.Derose
C
3

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.

For an example: http://ideone.com/L66Prq

#include <iostream>
using namespace std;

class PublicAbstract {
public:
    PublicAbstract() { }        
    virtual void doThings() =0;
};

class ProtectedAbstract {
protected:
    ProtectedAbstract() { }     
public:
    virtual void doMoreThings() =0;
};

class B: public PublicAbstract {
public:
    void doThings() { } 
};

class C: public ProtectedAbstract {
public:
    void doMoreThings() { } 
};

int main() {
    B b;
    C c;
    return 0;
}
Cloy answered 4/6, 2014 at 12:16 Comment(0)
C
2

A public constructor would not be very useful, since abstract classes cannot be instantiated in the first place.

A protected constructor makes sense: this way, a derived concrete class can provide its own public constructor that chains to the protected constructor of the base abstract class.

Charteris answered 4/6, 2014 at 12:11 Comment(0)
E
0

Protecetd ctor will make sure the ctor gets called by only the classes which derive from Abstract_base.

Public ctor is not suitable because the class contains a pure virtual method! How are you planning to instantiate a pure-virtual class if not via its child classes?

Endearment answered 4/6, 2014 at 12:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.