0

Possible Duplicate:
class has virtual functions and accessible non-virtual destructor

I got this code from following a tutorial by thenewboston:

#include <iostream>

using namespace std;

class Enemy {
public:
    virtual void attack(){};
};

class Ninja: public Enemy {
public:
    void attack(){
        cout << "ninja attack"<<endl;
    }
};

class Monster: public Enemy {
public:
    void attack(){
        cout << "monster attack"<<endl;
    }
};

int main() {
    Ninja n;
    Monster m;
    Enemy * enemy1 = &n;
    Enemy * enemy2 = &m;
    enemy1->attack();
    enemy2->attack();
    cin.get();
    return 0;
}

Why do I get these warnings:

class Enemy has virtual functions and accessible non-virtual destructor
class Ninja has virtual functions and accessible non-virtual destructor
class Monster has virtual functions and accessible non-virtual destructor
Community
  • 1
  • 1
  • 1
    [class has virtual functions and accessible non-virtual destructor c++](http://stackoverflow.com/questions/5827719/class-has-virtual-functions-and-accessible-non-virtual-destructorc/5827739#5827739) – Kazuki Sakamoto May 08 '11 at 23:58
  • Is this your actual code, what compiler are you using? I can compile and run this code without any warnings on vs2005, what warning level have you got set? – Craig May 09 '11 at 00:05

2 Answers2

4

The compiler just warns you, that the destructors of your derived classes (added by the compiler) are not virtual. In this case it is no problem and you can ignore the warning. But when your derived classes get additional data elements that need to be released properly in the destructor, you need to make the destructors virtual, so they get called using delete on an Enemy pointer (otherwise only the Enemy destructor gets called).

EDIT: Of course you do not have to make the destructors virtual in the derived classes' definitions, but in the base class's (or in both for clarity).

Christian Rau
  • 45,360
  • 10
  • 108
  • 185
2

Your compiler is urging you to add a virtual destructor for your three classes. In this specific case, it doesn't really matter, but it's generally a good idea to have a virtual destructor for any class that may be used polymorphically.

Consider the following example:

class Fight
{
public:
    Fight(Player* player, Enemy* enemy)
    {
        m_player = player;
        m_enemy  = enemy;
    }

    void playerAttack()
    {
        m_player.attack(m_enemy);
        if (m_enemy.isDead())
            delete m_enemy;
    }

private:
    Player* m_player;
    Enemy* m_enemy;
}

Here you delete a pointer to an Enemy-instance, which is probably a derived class. The derived class may have its own extra data members (on top of Enemy's data members) or special initialization code, but delete can only reach this code if Enemy and its child classes have virtual destructors. Otherwise, it would run Enemy's destructor, which may lead to very bad results.

Note that in your code, Monster and Ninja only ever get allocated on the stack, and they won't need virtual destructors (since the compiler knows the full-type of each object at compilation time). But in practice, it's very common to dynamically allocate polymorphic objects (i.e. instances of classes with public virtual functions). So as a rule, you should add virtual destructors to this kind of classes.

Boaz Yaniv
  • 6,334
  • 21
  • 30