2013-04-18 3 views
3

Если у меня есть класс, который выглядит примерно так:Нужно ли мне удалять базовые типы данных в деструкторе? C++

class SomeClass { 
    public: 
     SomeClass(int size) { 
        arr = new int[size]; 
        someInt = size/10; 
        }; 
     ~SomeClass() { 
         delete [] arr; 
         //do I need to somehow delete the int value 'someInt'? 
        }; 
    private: 
     int *arr; //pointer to dynamically allocated array 
     int someInt; 
} 

Что, собственно, должны содержаться в деструкторе, чтобы избежать утечек памяти?

Я знаю, что мне нужно удалить массив, поскольку он динамически распределен, но мне нужно что-либо делать с значениями int или другими базовыми типами данных?

Спасибо, Jonathan

+4

Нет - и вы должны использовать 'std :: vector' вместо выделения пространства вручную. –

+0

[Не так, но рекомендуется Q & A] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list?rq=1) :) – jrok

+0

@Jerry, это связано к назначению школы, где мне требуется использовать динамически выделенный массив в качестве его части. Мне также требуется деконструировать все в классе должным образом. – Jonathan

ответ

15

No.

Но не только для основных типов. Для всего, что вы не выделили new, вам не нужно звонить delete. Даже для указателей.

delete имеет (как-то) не имеет ничего общего с типом переменной члена. Важно то, что у вас выделено его (с new) в вашем конструкторе (или где-то еще в ваших методах класса).

Правило большого пальца

Have as many delete as new 
Have as many delete[] as new[]. 

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

Конечно иногда вам придется НЕdelete что вы БЫЛИ выделено, но кто-то указывает на (выделенных вами, но кто-то использует его).

+1

Просто потому, что класс ничего не выделял, не означает, что он не «владеет» тем, что нужно удалить, когда класс будет уничтожен. – 2013-04-18 18:59:02

+0

@ Джеймс Да. Правда. Но это не то, что он спрашивает. Я просто пытаюсь определить его основы. Я отредактирую его. – stardust

+0

Так, другими словами, в этом конкретном случае мне нужно удалить массив, как у меня уже есть? И как отметил @James, могут быть случаи, когда удаление может происходить где-то помимо деструктора в классе, где произошло распределение? – Jonathan

2

Нет, вы этого не сделаете. You only delete что выделено, используя new.

5

Нет, вам не нужно вручную удалять автоматические переменные. Только delete что вы new.

Кроме того, вы можете избежать необходимости удаления массива с помощью RAII с помощью интеллектуального указателя. Тогда вам не придется вручную определять деструктор; автоматически определяемый деструктор сделает то, что вам нужно.

class SomeClass { 
    public: 
     SomeClass(int size) 
      : arr {new int[size]} 
      , someInt = size/10; 
     {}; 

    private: 
     std::unique_ptr<int[]> arr; //pointer to dynamically allocated array 
     int someInt; 
} 

Это даже лучше использовать более специализированный тип, такой как std::vector вместо общего интеллектуального указателя:

class SomeClass { 
    public: 
     SomeClass(int size) 
      : arr (size) 
      , someInt = size/10; 
     {}; 

    private: 
     std::vector<int> arr; 
     int someInt; 
} 
+0

Я согласен с обоими случаями, и определенно тот факт, что использование векторов упростило бы то, что я пытаюсь сделать, но это касается назначения класса, где оба ваших решения запрещены. Мне нужно явно деконструировать массив, и я не могу использовать векторы.= P – Jonathan

+0

@Jonathan Если вам не разрешено использовать средства 'std', вы можете попробовать создать простую их реализацию самостоятельно. Вручную управлять ресурсами без таких помощников трудно. Вы могли бы даже больше узнать об этом. – bames53

+0

Я думаю, что одной из основных целей этого задания является понимание деконструкторов и правильное распределение и управление памятью (по крайней мере, в небольшом масштабе). Мне не нужно использовать его снова за пределами этого случая, но мне нужно продемонстрировать, что я это понимаю. В противном случае, поверьте, я был бы намного счастливее, используя векторы. =) – Jonathan

2

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

1

Вам нужно только удалить то, что вы новичок или удалить [], что вы новый []. Вы можете посмотреть в auto_ptr

2

Вы никогда не удаляете и не добавляете ничего, что является частью вашего объекта. Это предложение сразу указывает, почему вы не делаете ничего конкретного для int, но вы делаете что-то для указателя.

Сам int является частью вашего класса. Указатель является частью вашего класса. Фактически, все вещи, перечисленные в вашем классе, являются частью вашего класса. Следует отметить, что указатель является частью вашего класса, но pointee или Указанный объект нет. Указатель как таковой будет уничтожен (и будет вызван его деструктор, если это уместно), но указатель не будет.

+0

Благодарим вас за разъяснение. Я думаю, что потребность в явном уничтожении объекта, направленного на объект, теперь имеет для меня гораздо больше смысла. Я дам вам ответ, но я думаю, что ответ пользователя более точно отвечает на мой вопрос. Имейте +1 хотя. знак равно – Jonathan

Смежные вопросы