С указателями на объекты нельзя использовать механизм выделения malloc() и освобождения free() динамической памяти языка Си, так как выделение памяти под объект не вызывает его констуктор, в результате возникает неинициализированный объект, который ведёт себя непредсказуемо.
Чтобы не нарушать логики С++ нужен новый механизм работы с динамической памятью — операторы new и delete.
Иcпользование данных операторов с объектами и только их должно быть правилом!
Изменение приватных полей по-прежнему запрещено. Компилятор следит за этим, и выведет ошибку увидев, например, p2->age = 17;
Отлично! Задача решена.
Операция new предназначена для создания объекта.
Время жизни объекта, созданного с помощью new, не ограничивается областью видимости, в которой он был создан. Операция new возвращает указатель на созданный объект. Если объект является массивом, возвращается указатель на начальный элемент массива. Например, обе операции new int и new int[1] возвратят int* , а типом new int[i][10] будет int(*)[10]. Если описывается тип массива, все размерности, кроме первой, должны быть выражениями-константами с положительным значением. Первая размерность массива может задаваться произвольным выражением.
Операция delete уничтожает объект, созданный с помощью new.
Операндом delete должен быть указатель, который возвращает new. Эффект применения операции delete к указателю, который не получен в результате операции new, считается неопределенным и обычно приводит к опасным последствиям. Однако гарантируется, что удаление по указателю с нулевым значением безопасно.
Результат попытки доступа к удаленному объекту неопределен, а удаление объекта может изменить его значение. Более того, если выражение, задающее объект, является изменяемым адресом, его значение после удаления неопределено.
Результат удаления массива с помощью простого обращения delete не определен, так же как и удаление одиночного объекта с помощью delete [].
Операция delete вызывает деструктор (если он есть) для объекта, на который настроен ее операнд.
Нельзя удалять указатель на константу!
Для классических, не классовых типов в проекте может быть использован и старый механизм выделения и освобождения памяти malloc()/free(), но его никогда нельзя смешивать с new/delete.
Память выделена и освобождена в новом стиле
ОК. Память выделена и освобождена в старом стиле
Память выделена в старом стиле, а освобождена в новом. Ошибка!
Память выделена в новом стиле, а освобождена в старом. Ошибка!