本文介绍了虚拟功能无法正常运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是从thenewboston的教程中获得的代码:

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


推荐答案

您的编译器敦促您为您的三个类添加虚拟析构函数。在这种特定情况下,这并不重要,但是对于可能多态使用的任何类都具有虚拟析构函数通常是个好主意。

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.

请考虑以下内容例如:

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;
}

在此处删除指向敌人实例的指针,这可能是派生的类。派生类可能具有自己的额外数据成员(位于Enemy的数据成员之上)或特殊的初始化代码,但是 delete 仅在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.

请注意,在您的代码中,Monster和Ninja只会分配到堆栈上,它们不需要虚拟析构函数(因为编译器在编译时就知道每个对象的完整类型)。但是实际上,动态分配多态对象(即具有公共虚函数的类的实例)是很常见的。因此,通常应将虚拟析构函数添加到此类中。

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.

这篇关于虚拟功能无法正常运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 20:34
查看更多