О конструкторах / деструкторах и новых / удаляемых операторах в C ++ для пользовательских объектов - PullRequest
3 голосов
/ 25 декабря 2008

Предположим, у меня есть связанный список, который я создал сам. У него есть свой деструктор, который освобождает память. Этот связанный список не перегружает новые или удаляет.

Теперь я пытаюсь создать массив упомянутых связанных списков (открытое хеширование, если я правильно понимаю). Затем я выделяю необходимую память внутри конструктора этого открытого класса хеширования. Вызываемого внутри конструктора оператора new достаточно для правильного выделения памяти для массива, верно? Я не уверен, потому что я не перегружен новым для класса Linked List.

Кроме того, предполагая, что мой массив связанных списков называется элементами, могу ли я просто написать "delete [] elements" в деструкторе? Будет ли это вызывать деструктор для каждого элемента в массиве и правильно освободить память?

Наконец, если оба моих предположения верны (то есть мне не нужно перегружать new и удалять, чтобы использовать их с моим пользовательским классом), какой смысл перегружать такие операторы?

Ответы [ 3 ]

6 голосов
/ 25 декабря 2008

Да, вы правы. Равнина

elements = new LinkedList[N];

достаточно, чтобы выделить их. Вы можете получить к ним доступ

elements[i]->push(....);

и удалите их в своем деструкторе, как вы показали:

delete[] elements;

Компилятор запомнит, сколько элементов было выделено, и правильно вызовет деструктор для каждого списка. Точка перегрузки операторов new и delete заключается в предоставлении пользовательской стратегии выделения памяти. Например, вы можете предварительно выделить память и затем извлечь из этого пула, вместо того, чтобы каждый раз снова выделять память из ОС.

Но обратите внимание, вы должны написать конструктор копирования и оператор копирования. Поскольку, если кто-то копирует вашу хэш-карту, необходимо скопировать связанный список, а не только указатель. Или вы можете сделать конструктор копирования и оператор присваивания копий приватными и не определять их, запретив копии вашей хэш-карты:

....
private:
    MyHashMap(MyHashMap const& rhs);
    MyHashMap & operator=(MyHashMap const& rhs);
....
2 голосов
/ 25 декабря 2008

Оператор new выполняет две функции: выделяет память и вызывает конструктор.

Оператор delete вызывает деструктор, а затем освобождает память.

Массивы, созданные с помощью new [] , должны быть уничтожены с помощью delete [] .

Как правило, вам не нужно перегружать new или delete за исключением соображений производительности. У вас может быть предсказуемая схема распределения / освобождения, которая делает конкретную стратегию распределения очень подходящей (быстрое или низкое использование памяти).

Возможно, вы захотите взглянуть на эту страницу .

1 голос
/ 25 декабря 2008

Все ваши предположения верны.

Существует множество способов перегрузки new и delete, но это делается не часто. Одной из распространенных причин является отслеживание выделения памяти для выявления утечек памяти. Многие трекеры утечки времени компиляции делают это, но устарели из-за лучших внешних приложений, таких как valgrind. Вы также можете использовать такие вещи, как пул памяти.

...