Как инициализировать переменную родительского класса в под классе?
В классе "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 шт):
Пишете конструктор класса 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"; // выдаст ошибку
}
При наследовании, класс уже имеет под объект родительского класса,остается лишь инициализировать этот объект или списком инициализации или аргументами конструктора(если они есть).
Класс не функция, чтобы там выполнить какие то операции. Это инструкция для создания экземпляров, где можно объявить и определять члены этих экземпляров.
Если хотите, чтобы класс контролировал количество созданных животных, тогда это количество должно быть статическим членом, чтобы при каждым созданным объектом не пришлось в ручную увеличить число. Этим пусть
конструктор занимается.
Если хотите, чтобы 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;
}
то недостатки становятся очевидными. Мы хотим вывести количество свиней, но выводятся количество всех созданных животных. Ну и зачем тип животного должен быть членом, если он одинаков для каждого вида? Следовательно тип должен быть статическим константным членом каждого производного класса, наряду с не константным членом, хранящего информацию о количестве.
И так, мы имеем более яркое представление о том, что архитектуру лучше улучшить.