Сам C ++ не имеет никакого понятия о стеке или куче. Это детали реализации C ++, но обычно они переводятся в то, что стандарт называет объектами с автоматической продолжительностью хранения и объектами с динамической продолжительностью хранения .
. в смысле, ваш p_age
указывает на int
объект с динамической продолжительностью хранения (т.е. в куче) после назначения из new
. Однако p_age
(указатель, а не объект, на который он указывает) продолжительность хранения зависит от того, как создается его родительский объект типа Person
, к которому он относится подобъект, например, с Person person{42};
вТело функции, person
и person.p_age
будет иметь автоматическую продолжительность хранения (т. е. они находятся в стеке), тогда как *(person.p_age)
, объект, на который указывает person.p_age
, все еще имеет динамическую продолжительность хранения (т. е. живет в куче).
Невозможно проверить, имеет ли объект, на который указывает указатель, динамическую или автоматическую продолжительность хранения во время выполнения. Задача программиста - убедиться, что они не перепутаны, и вы, например, случайно вызываете delete
для указателя на объект автоматической длительности хранения. Вот почему вы должны редко использовать new
(который всегда создает объекты с динамической длительностью хранения) и вместо этого инкапсулировать каждый объект с динамической длительностью хранения объектом автоматического управления длительностью хранения, например, используя std::unique_ptr
, чтобы явные обращения кdelete
становятся ненужными.
В частности, в вашем примере, похоже, нет никакой причины для динамического выделения (будь то напрямую с new
или через std::unique_ptr
) вообще. «Возраст» должен быть частью «Человека», т. Е. Если «Человек» создан или уничтожен, то так же должен быть и его «возраст». Следовательно, p_age
должен иметь тип int
, а не int*
, и его следует просто назначить в конструкторе:
Person::Person(int age) : p_age(age) {
}
, который использует синтаксис списка инициализатора *1036* для непосредственного связыванияинициализировать (а не назначать после инициализации, как в вашем коде) p_age
со значением age
.