Сначала я бы определил ваш класс Person
следующим образом:
class Person {
int Age;
int ID;
protected:
Person(int age, int id): Age{age}, ID{id} {}
public:
virtual ~Person() = default;
};
То есть конструктор Person
сделан protected
, так что класс вне иерархии не может быть создан объект Person
и его деструктор сделаны virtual
, чтобы сделать его пригодным в качестве базового класса для типа polymorphi c.
Затем оба Child
и Adult
публично наследуются от Person
, как они у вас уже есть. Их конструкторы в итоге вызывают конструктор Person
с той же параметризацией, которую получают их конструкторы:
class Adult: public Person {
public:
Adult(int age, int id): Person(age, id) {}
// ...
};
class Child: public Person {
public:
Child(int age, int id): Person(age, id) {}
// ...
};
Наконец, для создания объектов, производных от Person
, я бы создал фабричную функцию ниже:
std::unique_ptr<Person> create_person(int age, int id) {
if (age < 18)
return std::make_unique<Child>(age, id);
else
return std::make_unique<Adult>(age, id);
}
Эта фабричная функция создает объект Child
, если возраст создаваемого лица меньше 18 лет. В противном случае он создает объект Adult
. Это - определение типа создаваемого объекта - выполняется во время выполнения.
EDIT: Вы задались вопросом, как объект Child
может стать объектом Adult
после его возраст достиг 18 лет.
Я бы предложил сделать состояние Person
объекта неизменным , чтобы каждый раз при создании возраста создавался новый * fre sh объект. человека увеличивается. Таким образом, создание нового объекта из существующего будет единственным способом увеличить возраст Person
, и в этот момент у вас будет возможность решить, создавать ли объект Child
или Adult
на основе новой эры.
Для этого сначала квалифицируйте элемент данных Age
в Person
как const
(вы можете сделать то же самое с ID
). Затем определите следующую функцию-член Person
, которая всегда создает новый объект (с тем же ID
) в результате увеличения объекта Person
Age
на единицу:
std::unique_ptr<Person> Person::increase_age() const {
return create_person(Age + 1, ID);
}
Как видите, он делегирует создание объекта фабричной функции, create_person()
, уже объясненной выше. Эта функция-член может вызываться как для объектов Child
, так и Adult
, поскольку она наследуется от Person
.