I would first define your class Person
like this instead:
class Person {
int Age;
int ID;
protected:
Person(int age, int id): Age{age}, ID{id} {}
public:
virtual ~Person() = default;
};
That is, Person
's constructor is made protected
so that a class outside the hierarchy can't create a Person
object, and its destructor is made virtual
to make it suitable as a base class for a polymorphic type.
Then, both Child
and Adult
publicly inherit from Person
, as you already have them. Their constructors end up calling Person
's constructor with the same parametrization their constructors receive:
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) {}
// ...
};
Finally, for creating objects that derived from Person
, I would create the factory function below:
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);
}
This factory function creates a Child
object if the to-create person's age is under 18. Otherwise, it creates an Adult
object. This – determining the type of the object to create – is done at run time.
EDIT: You wondered how a Child
object could become an Adult
object after its age has reached 18 years old.
I would suggest making the state of a Person
object immutable so that a fresh new object has to be created every time the age of a person is increased. This way, creating a new object from an existing one will be the only way to grow a Person
's age and, at that moment, you will have the control to decide whether to create a Child
or Adult
object based on the new age.
For doing this, first, qualify the Age
data member in Person
as const
(you can do the same with ID
). Then, define the following Person
's member function which always creates a new object (with the same ID
) resulting from increasing a Person
's object Age
by one:
std::unique_ptr<Person> Person::increase_age() const {
return create_person(Age + 1, ID);
}
As you see, it delegates the creation of the object to the factory function, create_person()
, already explained above. This member function can be called on both Child
and Adult
objects since it inherits from Person
.