C++ protected constructor for abstract classes

cconstructor

i'm trying to figure out the difference between public constructor and protected constructor for an abstract base class.
Let's say that i have two classes:

Abstract Base Class: Monster

class Monster
{
public: // or protected?? what is the techincal difference?
    Monster(string name)
    {
        _name = name;
    }
public:
    virtual void attack() = 0;

    const string getName() const
    {
        return _name;
    }

private:
    string _name;

};

Concrete Child Class: Spider

class Spider : public Monster
{
public:
    Spider(string name) : Monster(name)
    {

    }

    void attack() override
    {
        cout << getName() << ":(Spider) is attacking!" << endl;
    }
};

Now if i try to create a Monster instance:

int main()
{
    Monster monster1 { "Abstract Monster Not Allowed" }; // Error
}

Error:
Object of abstract class type "Monster" not allowed:
Monster:: Attack is a pure virtual function.

This perfectly makes sense, but so a 'public constructor' is an alias of 'protected constructor' in an abstract class?
In which situation I could use protected constructor for an abtract class?

Thanks in advance.

Best Answer

Think of a coin as being an abstract base class. You do not want to instantiate a coin object directly, but you will want to construct derived types of coins that have different attributes such as Country of Origin, Face Value and then set the properties accordingly such as the size, weight and material they are made of. We don't want to have a bunch of coin base classes laying around in some container because there isn't enough of information to describe that coin object. Therefore this coin object is abstract or is a concept. However the derived objects of this coin base class such as an American Silver Dollar, or A German Franc etc., are real objects that can be instantiated since they are real objects and enough information is known about them while constructing them.

Due to the nature of this and due to how class encapsulation works even if the base class is not abstract meaning there is no need for purely virtual functions then the coin base class's constructor should be protected! Even if you do have the need for purely virtual methods within this coin class it is still good practice to keep the constructor protected. This makes the source more readable to others when they are looking at your class interface and they see a protected constructor. They know that this class can not be directly instantiated.

Now let us say that another class has the relationship of has a "coin" class such as a bank class or a mint class where the mint class creates the coins & the bank class holds the coins, it is possible that these classes could have the friend access modifier to the protected coin constructor so that they can create instances of these coins before any information is available and store them into containers to later be processed. Think of this as a pre-batch operation and with this layout the coin base class serves as a template (not a c++ programming template).