Если я удалю класс, автоматически ли удаляются его переменные-члены?
Я занимаюсь исследованиями, и ничего существенного не появилось, поэтому я пришел сюда.
Я пытаюсь избежать утечек памяти, поэтому мне интересно:
Скажем, у меня есть класс MyClass
с членами int
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
?
Ответы
Ответ 1
Когда выполняется delete mc
, компилятор вызывает деструктор объекта (MyClass::~MyClass()
) и затем освобождает связанную с ним память.
Деструктор по умолчанию (если вы не объявляете свой собственный) вызывает деструкторы всех переменных-членов, начиная от последнего до первого путем объявления (т.е. в этом случае c
, затем b
, затем a
). Поскольку в этом примере те члены POD типов (они не имеют деструктора) не работают.
Ответ 2
Правило очень просто: каждый объект, созданный с помощью new
, должен быть уничтожен ровно один раз с помощью delete
; каждый массив, созданный с помощью new[]
, должен быть уничтожен ровно один раз с помощью delete[]
; все остальное не должно быть удалено. Таким образом, ваш код правильный; вы удаляете mc
после создания его с помощью new
и не удаляете элементы, которые не были созданы с помощью new
.
Применение правила может быть довольно сложным, когда поток программы усложняется (особенно при использовании исключений); по этой причине гораздо лучше не удалять объекты самостоятельно, а сразу использовать результат new
для инициализации умного указателя для управления объектом для вас.
Ответ 3
Переменные внутри класса имеют класс scope и уничтожаются, когда класс. Единственное, что вам нужно беспокоиться, это указатели - они должны быть надлежащим образом рассмотрены в вашем деструкторе.
Ответ 4
Когда вы освобождаете объект, все его переменные-члены также автоматически освобождаются. Итак, в вашем случае да, a
, b
и c
все освобождены.
Однако, если одна из ваших переменных-членов является указателем, только сам указатель автоматически освобождается, не объект, на который он указывает, - это наиболее распространенный случай, когда вам приходится писать собственный деструктор.
Ответ 5
Члены класса являются частью структуры памяти класса.
Итак, когда вы освобождаете эту память, члены освобождаются вместе с ней.
Примечание:
Если у вас есть указатели, они также уничтожены, НО память, на которую они указывают, не уничтожена.
Подробнее о потреблении памяти класса:
Классы С++
Ответ 6
delete
вернет память, содержащую ваш объект. Если ваш тип поддерживает указатели на динамически распределенную память, вам нужно будет очистить их внутри вашего деструктора.
Что касается вашего конкретного quesiton:
после того, как я вызываю delete mc, будет также удалено a, b и все содержимое c? Или я должен сделать это явно в деструкторе MyClass?
Они будут очищены для вас, поскольку они не были распределены динамически.
Ответ 7
Ваши три переменные не были выделены с помощью new
, поэтому их вообще не нужно было бы удалять.
Они будут разрушены, если ваш класс delete
d (поскольку они были выделены, когда ваш класс был new
d), но это не то же самое, что и удаление.
Ответ 8
В вашем конкретном примере ответ да. Это потому, что вы выделили переменные-члены в стеке. Если вы использовали 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;
}
}
}