Как инициализировать переменную родительского класса в под классе?

В классе "Pig" я хочу инициализировать переменную "type", которую объявил в классе родителя "Animals", так-же, как это делают в "main()", сначала создают объект класса, а после '.' вызывают методы, объявляют переменные и т.д. Я как понимаю сделать этого не получиться. Но есть ли способ инициализировать её?

class Animals
{   
    public:
        string type;
        double age;
        int how_much;
        double weight;

    void spawn_animal()
    {
        cout << "New " << type << " is spawned!" << endl;
        cout << "Quantity: " << how_much; 
    }
};

class Pig: public Animals
{
    public:
        Animals pig;
        pig.type = "\"Pig\"";   // Здесь ошибка...     
};

Ответы (2 шт):

Автор решения: DmitryK

Пишете конструктор класса Animals, который инициализирует переменную type переданным значением.
Потом пишете конструктор класса Pig, который вызывает инициализирующий конструктор Animals.

class Animals
{   
    public:
        int how_much;
        string type;
        Animals(const char* str) : type(str) {}
}

class Pig: public Animals
{
    public:
        Pig() : Animals("Pig") {}
}

int main()
{
    Pig pig;
    pig.how_much = 1;
    pig.spawn_animal();
}

Аналогично для всех остальных членов класса.
Таким образом можно инициализировать константные члены класса. Например если по логике работы программы тип животного один раз инициализируется и больше не должен меняться, то его можно объявить константным - он тогда один раз проинициализируется и при попытках его изменить будет выдаваться ошибка.

class Animals
{   
    public:
        const string type;
}

int main()
{
    Pig pig; 
    pig.type = "Dog"; // выдаст ошибку
}
→ Ссылка
Автор решения: AR Hovsepyan
  • При наследовании, класс уже имеет под объект родительского класса,остается лишь инициализировать этот объект или списком инициализации или аргументами конструктора(если они есть).

  • Класс не функция, чтобы там выполнить какие то операции. Это инструкция для создания экземпляров, где можно объявить и определять члены этих экземпляров.

  • Если хотите, чтобы класс контролировал количество созданных животных, тогда это количество должно быть статическим членом, чтобы при каждым созданным объектом не пришлось в ручную увеличить число. Этим пусть
    конструктор занимается.

Если хотите, чтобы how_much хранил не количество любого животного, а для каждого вида были свои данные, то не базовый класс должен содержать его, а каждый производный класс должен иметь свой статический how_much. Допустим нас устраивает первый вариант...

И еще нужно создать возможность установить данные о весе и возрасте животного. Что касается типу, то у каждого класса свой тип

class Animals
{
public:
    const string type;
    double age;    
    double weight;
    static inline int how_much; 

    void set_data(double age, double weight)
    {
        this->age = age;
        this->weight = weight;
    }
    void spawn_animal()
    {
        cout << "New " << type << " is spawned!" << endl;
        cout << "Quantity: " << how_much;
    }
    /* Деструктор, при уничтожении животного(ых),
     уменьшит значение количества*/
    ~Animals() { if (how_much) --how_much; }
};

class Pig : public Animals
{
public:
    Pig() : Animals{ "\"Pig\"", .5, 14.3 } 
    {     ++Animals::how_much;     }
    /*то есть в списке инициализации
     инициализировали члены животного, 
     а в теле  конструктора увеличиваем  количество*/          
};

 //можно создать любой вид животного
 class Lew : public Animals {
 public:
    Lew() : Animals{ "\"Lew\"", .5, 14.3 } 
    {    ++Animals::how_much;    }
 };
 //...

В таком виде, если написать программу:

int main() {
  {
    Pig pig[3];
    Lew lew;
    pig[0].spawn_animal(); //4
  }// выход из области видимости
    cout << '\n';
    //теперь нет ни одного животного, но появилась еще одна свинья
    Pig pig;
    pig.spawn_animal(); //1
    return 0;
}

то недостатки становятся очевидными. Мы хотим вывести количество свиней, но выводятся количество всех созданных животных. Ну и зачем тип животного должен быть членом, если он одинаков для каждого вида? Следовательно тип должен быть статическим константным членом каждого производного класса, наряду с не константным членом, хранящего информацию о количестве.

И так, мы имеем более яркое представление о том, что архитектуру лучше улучшить.

→ Ссылка