Constructor Initialiser List for base-class's protected variable

Constructor initialiser list is a good coding style for its own class member initialisation.  I tried to initialise the base class member in the sub-class constructor initialiser list, but it didn't work. Read below the reasons. 

#include <iostream>
using namespace std;

class Army                         // Class declaration
{
private:
    static int numberSuffix;     // Static member variable
    int armyCode;                // Non-static member variable
protected:
    string name;
public:
    Army(int armyCode);
    void enrollment(int numberSuffix, int armyCode);
    string getPatientName() { return name; }
};

class ArmyHospital : public Army {
    ArmyHospital() : Army(508), name("Shirley"); 
};

void Army::enrollment(int numberSuffix, int armyCode)
{
    Army::armyCode = 100; // error
    this->armyCode = 100; // fine - Non-static
    armyCode = 100; // fine

    numberSuffix = 890; // fine
    Army::numberSuffix = 890; // fine
}


Line 18: error: class 'ArmyHospital' does not have any field named 'name'

This is not possible as name is not the member of the ArmyHospital rather a member of an Army. Only Army constructor can initialise this. I guess It is still allowed  if it is in public section, but it still threw me an error. 

#include <iostream>
using namespace std;

class Army                         // Class declaration
{
private:
    static int numberSuffix;     // Static member variable
    int armyCode;                // Non-static member variable
protected:
    //string name;
public:
    string name;
    Army(int armyCode);
    void enrollment(int numberSuffix, int armyCode);
    string getPatientName() { return name; }
};

class ArmyHospital : public Army {
    ArmyHospital() : Army(508), name("Shirley"); 
};

void Army::enrollment(int numberSuffix, int armyCode)
{
    Army::armyCode = 100; // error
    this->armyCode = 100; // fine - Non-static
    armyCode = 100; // fine

    numberSuffix = 890; // fine
    Army::numberSuffix = 890; // fine
}
error: class 'ArmyHospital' does not have any field named 'name'

(Must Read) * - Members of the base class can't be initialised in the derived class constructor initialiser's list even if they are protected or public members of base class. Constructor initialiser list is to initialise only its own class's members. But, you can initialise the base class members in the body of the derived class constructor.

If the variable is moved to public, the encapsulation concept is destroyed which is not a good sign. So better initialise them in the base class constructor. This is a good solution. 

In my case, you can't initialise them in the base class as the value is given during the sub-class initialisation. So, I ruled out the first option that it can't be initialised with constructor initialiser list. I was thinking what to do next? Then and idea popped out that I can initialise them in the constructor definition if only it is a protected member of the base class. 

#include <iostream>
using namespace std;

class Army                         // Class declaration
{
private:
    static int numberSuffix;     // Static member variable
    int armyCode;                // Non-static member variable
protected:
    string name;
public:
    Army(int armyCode);
    void enrollment(int numberSuffix, int armyCode);
    string getPatientName() { return name; }
};

class ArmyHospital : public Army {
    ArmyHospital() : Army(508) {
       name = "Shirley";
    }
};

void Army::enrollment(int numberSuffix, int armyCode)
{
    Army::armyCode = 100; // error
    this->armyCode = 100; // fine - Non-static
    armyCode = 100; // fine

    numberSuffix = 890; // fine
    Army::numberSuffix = 890; // fine
}

When you have different value/functionality/lines of code for the same variable(Eg: name) in two different sub-classes (Eg: ArmyHospital, ArmyStore) that are derived from same super class (ie Army), keep a single variable in the super class but initialise them in the derived class constructors. 


Comments