Если я удалю класс, будут ли автоматически удалены его переменные-члены? - PullRequest
24 голосов
/ 06 июня 2011

Я занимался исследованиями, и ничего подходящего мне не пришло, поэтому я пришел сюда.

Я пытаюсь избежать утечек памяти, поэтому мне интересно:

Скажите, что у меня есть класс MyClass с членом int s a и b, а также int array c, которые заполняются функцией-членом:

class MyClass
{
    public:
        int a, b;
        int c[2];
        void setVariables() 
        {
            a, b = 0;
            for (int i = 0; i < 2; i++) 
            {
                c[i] = 3;
            }
        }
};
int main(int argc, char* argv[])
{
    MyClass* mc = new MyClass();
    mc->setVariables();
    delete mc;
} 

Теперь, после того как я вызову delete mc, будет a, b, а также удалить все содержимое c?Или мне придется сделать это явно в деструкторе MyClass?

Ответы [ 8 ]

33 голосов
/ 06 июня 2011

Правило очень простое: каждый объект, созданный с помощью new, должен быть уничтожен ровно один раз с помощью delete;каждый массив, созданный с помощью new[], должен быть уничтожен ровно один раз с помощью delete[];все остальное не должно быть удалено.Итак, ваш код верен;Вы удаляете mc после его создания с помощью new и не удаляете элементы, которые не были созданы с помощью new.

Применение правила может быть довольно сложным, когда выполнение программы усложняется (особенно когдаучаствуют исключения);по этой причине гораздо лучше не удалять объекты самостоятельно, а немедленно использовать результат new для инициализации интеллектуального указателя для управления объектом за вас.

29 голосов
/ 06 июня 2011

Когда выполняется delete mc, компилятор вызывает деструктор объекта (MyClass::~MyClass()) и затем освобождает память, связанную с ним.

Деструктор по умолчанию (когда вы не объявляете свою собственную) вызывает деструкторы всех переменных-членов в порядке от последнего к первому по объявлению (то есть, в данном случае, c, затем b, затем a). Поскольку в этом примере членами являются POD-типы (у них нет деструктора), работа не выполняется.

6 голосов
/ 06 июня 2011

Члены класса являются частью структуры памяти класса.

Итак, когда вы освобождаете эту память, члены освобождаются вместе с ней.

Примечание:
Если у вас есть указатели, они тоже уничтожаются, НО память, на которую они указывают, не уничтожается.

Подробнее о потреблении памяти классом:

C ++ Классы

4 голосов
/ 06 июня 2011

Для вашего конкретного примера ответ - да.Это потому, что вы разместили переменные-члены в стеке.Если бы вы использовали new для выделения памяти для переменных-членов, ответ был бы отрицательным и потребовал бы явного удаления переменных-членов в деструкторе класса.

class MyClass(): heapVariabl(NULL)
{  
   MyClass()
   {}

   ~MyClass()
   {
     delete heapVariable; 
   }   

   int a, b;     
   int[2] c;     
   int *heapVariable;
   void setVariables()      
   {         
     a, b = 0;       
     heapVariable = new int; // <- requires deletion in destructor to free memory
     *heapVariable = 0;
     for (int i = 0; i < 2; i++)          
     {             
       c[i] = 3;          
     }     
   } 


} 
4 голосов
/ 06 июня 2011

Переменные внутри класса имеют область видимости класса и уничтожаются, когда класс.Единственное, о чем вам нужно беспокоиться, это указатели - они должны быть исправлены соответствующим образом в вашем деструкторе.

3 голосов
/ 06 июня 2011

Когда вы освобождаете объект, все его переменные-члены также автоматически освобождаются. Итак, в вашем случае, да, a, b и c все освобождены.

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

1 голос
/ 06 июня 2011

Ваши три переменные не были распределены с помощью new, поэтому их вообще не нужно будет удалять.

Они будут уничтожены , когда ваш класс delete d (как они были распределены, когда ваш класс был new d), но это не то же самое, что удаление.

1 голос
/ 06 июня 2011

delete вернет память, которую содержит ваш объект. Если ваш тип поддерживает указатели на динамически выделяемую память, вам нужно очистить их внутри деструктора.

Что касается вашего конкретного задания:

после того, как я вызову delete mc, будут ли также удалены a, b и все содержимое c? Или мне придется делать это явно в деструкторе MyClass?

Они будут очищены для вас, поскольку они не были распределены динамически.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...