2014-01-30 2 views
0

Я создал подкласс, B, для класса, который я буду называть А.Создание «нового» экземпляра решает проблему деструктора?

Я написал этот код для работы, поэтому я буду обобщать фактический код:

class A 
{ 
public: 
    A() 
    { 
    important_variable = new Type(); 
    ... 
    }; 

    ~A (void) { delete(important_variable); };  // Default destructor 
    // more methods 

protected: 
    Type  *important_variable; 
}; 

class B : public A 
{ 
public: 
B() : A() { important_variable = another_var; } 
~B() {}; 

Type *another_var; 
}; 

Наличие этого кода для B вызвало сбой моей программы с помощью «Необработанного исключения».

Теперь, когда я изменить код для класса B к этому:

class B : public A 
{ 
public: 
B() : A() { another_var = new Type(); important_variable = another_var; } 
~B() {}; 

Type *another_var; 
}; 

Исключение уходит.

Я думаю, что мой исходный код для B вызвал мою программу, потому что A пыталась удалить переменную, на которую все еще указала другая переменная. Правильно ли это рассуждение? Почему новый код для B заставляет мою программу работать?

+0

Ваши рассуждения, вероятно, правильные (не могу сказать, не видя больше кода). Второй код работает, потому что вы создаете новый объект для каждого экземпляра, поэтому каждый раз, когда вы его удаляете, он не наступает на носки других. Но ваш код имеет утечки памяти. Вы не можете просто переназначить указатель, не делая что-то о объекте, на котором он указывал. – Dave

ответ

2

Есть много недостатков в вашем коде, но один, скорее всего, причиной аварии эта линия:

important_variable = another_var; 

another_var не указывает где-нибудь, что может быть удален. Но important_variable делается для того, чтобы указывать на то же место, а затем удаляется в конструкторе A.

Ваше «решение» маскирует проблему за счет утечки памяти. Когда вы сделаете это

another_var = new Type(); important_variable = another_var; 

оригинальный динамически распределяемой Type объект, который important_variable указал на утрачивается.

Кроме того, вам необходимо следовать за rule of three.

+0

Первый код также имеет утечку памяти. – Dave

+0

Как я могу избавиться от утечки памяти, сохраняя при этом существующую функциональность? – Undefined

+0

@ Даве Да, это так. – juanchopanza

0

новые и удаленные предназначены только для распределения кучи. Я подозреваю, что в вашем первом списке класса B another_var, скорее всего, выделен в стеке, и именно это вызывает исключение в деструкторе. Кроме того, всякий раз, когда у вас есть базовый класс, вы действительно должны сделать его деструктор virtual.

0

Оригинальная версия разбилась, потому что вы установили important_variable в uninitialised another_var, а затем попытались удалить это неинициализированное значение. В «исправленной» версии вы, по крайней мере, не удаляете неинициализированные переменные, но все же в ней содержится утечка памяти - вы назначаете новую выделенную память important_variable, а затем сразу же присваиваете этой переменной значение another_var, поэтому первоначально выделенная память не является дольше доступны и будут течь.

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