Допустим, есть класс:
class MyClass1
{
int a;
string s;
...
};
class MyClass2
{
list<MyClass1> lst;
}
Как правильно для MyClass2
- объявить деструктор, который бы полностью уничтожал контейнер?
Лично я пишу так:
~MyClass2()
{
this->lst.clear();
this->lst.shrink_to_fit();
}
Но this->lst.clear();
вызывает деструктор для каждого объекта контейнера, а -
this->list.shrink_to_fit();
- "сжимает" размер буфера в соответствии с size
. Но, например, когда size=0, capacity=1
, т.е в любом случае, контейнер будет находиться в памяти, пусть даже и "условно" - не имея в себе элементов.
Вопрос: как полностью удалить контейнер из памяти?
Уже не первый раз замечаю подобные ситуации, когда в деструкторе какого-либо класса, содержащего контейнеры (типа std::vector
, std::list
и т.п.), управляющие временем жизни своих объектов зачем-то выполняют ручную очистку. В большинстве случаев это делать не нужно, когда умирает объект, содержащий контейнер, автоматически убивается и контейнер. В свою очередь деструктор контейнера вызывает деструкторы содержащихся на тот момент элементов контейнера и так по цепочке.
Таким образом, если элементы контейнера имеют (или не требуют вовсе) деструкторы, полностью уничтожающие себя, никакой ручной работы не требуется. Но если, скажем, по какой-то причине, вы храните в контейнере что-то типа сырых указателей, для которых ранее была выделена память, то, конечно, такие указатели нужно освободить (выполнить соответствующую форму delete
) до того, как информация о них (адреса, по которым выделена память) будет уничтожена деструктором контейнера. В частности пройтись по ним соответствующим циклом. Но даже в таких случаях лучше положиться на подходящие умные указатели (например, std::unique_ptr
или std::shared_ptr
), чтобы избежать ненужной ручной работы по уничтожению (написанию деструктора).
После shrink_to_fit
пустого контейнера capacity
будет равно 0. А в деструкторе класса MyClass2
ничего писать не надо, так как деструктор списка сам все подчистит.
Если контейнер list хранит именно элементы MyClass1, а не указатели на них, то в деструкторе с этим контейнером ничего делать не надо, он сам всё почистит при разрушении объекта типа MyClass2.
Компилятор генерирует некоторое количество "умолчательного" кода для поддержки ООП. В том числе умолчательный деструктор, если вы не объявляете свой кастомный вариант. Умолчательный деструктор вызывает деструкторы всех экземплярных полей класса, т.е. в вашем случае и list
.
А std::list
, в свою очередь, достаточно умён, чтобы прибрать за собой, поэтому вашей задачей будет лишь реализация логики деструктора MyClass1
, экземпляры которого хранятся в списке, если в этом есть необходимость (MyClass1
содержит неуправляемые ресурсы, требующие ручного освобождения).
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Microsoft говорит нам, что мы можем модифицировать поток печати посредством разработки плагинов для драйвера печати
Необходимо считать в std::string байты файлаОдно из требований: поддержка юникодных имен файлов
Хотите улучшить этот вопрос? Переформулируйте вопрос так, чтобы он был сосредоточен только на одной проблеме