Я создал класс для создания связанного списка. Объявление класса выглядит следующим образом:
class LinkedList
{
private:
int data;
LinkedList *next;
static int count;
public:
LinkedList(void);
~LinkedList(void);
int insert(int arg);
int remove(int arg);
bool find(int arg);
};
Как я могу убедиться, что все узлы этого связанного списка удалены? Деструктор несет ответственность за удаление только одного узла. Раньше я раньше делал связанный список, но никогда не думал об очистке памяти.
Наивная реализация
~LinkedList() {delete next;}
выполнит правильную вещь - delete
вызовет деструктор на следующем элементе, который удалит следующий за ним и т.д., чтобы удалить весь список.
Однако это означает, что деструкторы называются рекурсивно, так что удаление очень длинного списка может привести к переполнению стека. Итерация может быть лучше:
~LinkedList() {
while (LinkedList * head = next) {
next = head->next;
head->next = nullptr;
delete head;
}
}
Как отмечалось в комментариях, было бы более целесообразно иметь отдельные классы List
и Node
, List
отвечает за управление памятью, а Node
- простой агрегат, содержащий данные и ссылку. Тогда там меньше возможностей для ошибки в деструкторе, так как не нужно сбрасывать никаких указателей, чтобы предотвратить рекурсию:
struct Node {
int data;
Node * next;
};
struct List {
Node * head;
~List() {
while (Node * victim = head) {
head = victim->next;
delete victim;
}
}
};