Есть класс Cinema, а так же производные от него. В консольном приложении я создаю список этих классов.
auto cinemas = new std::list<Cinema*>();
cinemas->push_back(new ImaxCinema("Victory square 15/6", "Imax 1", 150, 150));
cinemas->push_back(new Cinema3D("Victory square 16/1", "3D-Cinema", "Spectrum", 14));
cinemas->push_back(new DriveInCinema("Victory square 17/89", "Drive-In", 15, 102.3));
Позже, с помощью цикла, я вывожу содержимое.
for (auto iterator = cinemas->begin(); iterator != cinemas->end(); iterator++)
{
(*iterator)->write();
}
Затем очищаю список и освобождаю память выделенную под список.
cinemas->clear();
delete cinemas;
Вопрос: вызывается ли delete для каждого элемента в списке? Как это можно проверить?
Нет, память неявно не освобождается. Мало того, после вызова clear() Вы потеряли все имеющиеся указатели и, если они нигде более не сохранены, то Вы уже не сможете освободить память.
Вы можете освободить память в цикле, перед вызовом clear():
for (auto p: *cinemas) {
delete p;
}
cinemas->clear();
delete cinemas;
Также Вы можете использовать умные указатели:
auto cinemas = std::make_unique<std::list<std::unique_ptr<Cinema>>>();
cinemas->push_back(std::make_unique<ImaxCinema>("Victory square 15/6", "Imax 1", 150, 150));
cinemas->push_back(std::make_unique<Cinema3D>("Victory square 16/1", "3D-Cinema", "Spectrum", 14));
cinemas->push_back(std::make_unique<DriveInCinema>("Victory square 17/89", "Drive-In", 15, 102.3));
cinemas->clear();//"Умные" указатели уничтожат объекты, которыми владеют
cinemas.reset();//Удаление объекта, которым владеет cinemas
//Или совсем ничего не нужно вызывать, объект будет уничтожен при выходе из области видимости
Формально педантично-правильный способ удаления элементов из контейнера "голых" указателей должен выглядеть примерно так
while (!cinemas->empty())
{
Cinema *cinema = сinemas->back();
cinemas->pop_back();
delete cinema;
}
delete cinemas;
Идея заключается в том, чтобы ни в какой момент времени в контейнере не хранились невалидные указатели. Т.е. в первую очередь удаляется элемент из контейнера, и только затем уничтожается объект, на который этот элемент указывал.
Вариант, который начинает с удаления всех указуемых объектов и только потом удаляет элементы списка, является практически приемлемым для std::list<>, но запросто может привести к проблемам с другими типами контейнеров (в частности, с ассоциативными контейнерами).
Удалять вручную.
for(auto cinema: *cinemas) delete cinema;
cinemas->clear();
Заставить компилятор сделать это за вас:
auto cinemas = new std::list<std::unique_ptr<Cinema>>();
cinemas->push_back(std::make_unique<ImaxCinema>("Victory square 15/6", "Imax 1", 150, 150));
cinemas->push_back(std::make_unique<Cinema3D>("Victory square 16/1", "3D-Cinema", "Spectrum", 14));
cinemas->push_back(std::make_unique<DriveInCinema>("Victory square 17/89", "Drive-In", 15, 102.3));
cinemas->clear();
PS. А cinemas должен быть указателем?
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости