Допустим, есть класс:
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
содержит неуправляемые ресурсы, требующие ручного освобождения).
Виртуальный выделенный сервер (VDS) становится отличным выбором
Microsoft говорит нам, что мы можем модифицировать поток печати посредством разработки плагинов для драйвера печати
Необходимо считать в std::string байты файлаОдно из требований: поддержка юникодных имен файлов
Хотите улучшить этот вопрос? Переформулируйте вопрос так, чтобы он был сосредоточен только на одной проблеме