2016-02-03 3 views
3

Projectile является подклассом Node. Я хочу, чтобы вызывал деструктор Projectile.C++: Неправильный деструктор, вызываемый

Примечание: В сценарии реальной жизни, у меня есть список Node*, которые Projectile, Player или Enemy, каждый со своим собственным деструктора.

Node не имеет определенного деструктор в .h file (я предполагаю, что он использует по умолчанию.)

Node* p = new Projectile(); 
    delete(p); //Projectile destructor is never called 
+1

Возможный дубликат [Когда использовать виртуальные деструкторы?] (Http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors) – LogicStuff

+0

Вы имеете в виду, что 'Projectile' наследует от' Node' (если это так, 'суперкласс' является неправильным термином, чтобы связать« Снаряд »с« Узлом »)? – crashmstr

+0

Деструктор по умолчанию не является виртуальным. Если этого еще нет, включите уровень предупреждения компилятора (-Wall должно быть достаточно для этого в g ++), и вы увидите, что компилятор говорит вам, что написанное вами не будет работать. – user4581301

ответ

4

Во-первых, это, кажется, довольно ясно из вашего вопроса, что Projectile является подкласс из Node (см this Wikipedia entry).

Если у вас есть класс, как Node, который построен для подклассов, то вы должны убедиться, что его деструктор виртуальный:

class Node 
{ 
... 
    virtual ~Node(); 
}; 

Это заставит компилятор вызвать соответствующий класс s destructor when you delete` указатель суперкласса.

(Другой вопрос состоит в том, следует ли это быть чисто виртуальными.)

+0

Знаете, я Я никогда не пробовал чистый виртуальный деструктор. Это происходит в очереди за экспериментом завтра. – user4581301

+0

Почему все функции не всегда виртуальны? Есть ли преимущество, чтобы они не были виртуальными? – RainingChain

+0

Существует несколько причин. Один из них заключается в том, что с их использованием возникают накладные расходы во время выполнения, а философия C++ - «платить только за ту функцию, которую вы используете». У Бьярна Страуструпа есть книга об этих вещах; что-то вроде «Дизайн и эволюция языка C++». –

2

Вы должны сделать деструктор Node быть virtual, по умолчанию один (невиртуальном) не удовлетворяет потребностям здесь, то есть динамический полиморфизм не будет работать.

class Node { 
public: 
    virtual ~Node() {} 
} 
2

C++ статического типа язык, так что из этого утверждения Node* p = new Projectile(); компилятора видит р как объект Node. При разрушении p он будет вызывать деструктор класса Node.

Чтобы преодолеть этот сценарий, на картинке появляется virtual.

Код:

class Node { 
    public: 
    virtual ~Node() { 
     //delete resources allocated in Node class 
    } 
}; 

class Projectile : public Node { 
    public: 
    ~Projectile() { 
     //delete resources allocated in Projectile class 
    } 
}; 
0

Короткий ответ:

Сделайте свой деструктор в Node виртуальной.

class Node { 
    // Stuff... 
    virtual ~Node(); 
}; 

Not-So-Краткий ответ:

Когда Projectile и подобные, которые наследуют Node, элементы данных и функции, унаследованные от Node. Производный класс может переопределить или заменить фактическое определение функции в родительском классе. Это переопределение происходит либо во время компиляции, либо во время выполнения, в зависимости от погоды функция в базовом классе объявляется «виртуальной».

В случае не виртуального деструктора деструктор, вызываемый, определяется типом указателя. Поэтому, хотя указательная переменная p указывает на экземпляр Projectile, delete(p) вызовет деструктор, определенный в Node.

В случае виртуального деструктора деструктор, подлежащий вызову, определяется во время выполнения.Таким образом, независимо от типа указателя деструктор, который вызывается, будет тем, который определен в объекте, указанном в p.

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