对虚函数C++感到困惑

Hud*_*den 2 c++ virtual function

我是一个c ++ n00b,我不确定我是否找到了合适的地方,但我对此感到困惑:

include <iostream>

using namespace std;

class Enemy
{
    public:
        void sayHere()
        {
            cout<<"Here"<<endl;
        }
        virtual void attack()
        {
        }
};

class Monster: public Enemy
{

    public:
        virtual void attack()
        {
            cout<<"RAWR"<<endl;
        }

};

class Ninja: public Enemy
{

    public:
        virtual void attack()
        {

            cout<<"Hiya!"<<endl;
        }
};

int main()
{
    Ninja n;
    Monster m;
    Enemy enemies[2];
    enemies[0] = m;
    enemies[1] = n;

    for(int i = 0; i<2; i++)
    {
        enemies[i].sayHere();
        enemies[i].attack();//Will not be overriden
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么Monster或Ninja类中的attack()函数不被覆盖?任何帮助,甚至链接,将不胜感激.

Jon*_*son 5

做就是了:

Enemy* n = new Ninja();
Enemy* m = new Monster();

n->sayHere();
n->attack();
m->sayHere();
m->attack();

delete n;
delete m;
Run Code Online (Sandbox Code Playgroud)

那应该按你的意愿去做.你需要使用指针才能工作.原因在于动态绑定的工作方式.

只要程序声明了C++虚函数,就会为该类构造一个v表.v表包含类的虚函数的地址和派生类的每个对象的函数的指针.每当对c ++虚函数进行函数调用时,v-table用于解析函数地址.这是动态绑定在虚函数调用期间发生的方式.

这个想法是,编译器根据对象的内存地址存储指向每个方法的指针.它需要指针来访问表并调用适当的函数指针.想想你是否想编写一个OO版本的C,你会如何提供继承和多态这样的机制?当你以这种方式想到它时,这是有道理的.

我刚刚读到你正在从JAVA转移.在JAVA中,大多数对象都存储在堆上.这一切都只是暗示.

JAVA的

Enemy n = new Ninja();
n.attack();
Run Code Online (Sandbox Code Playgroud)

大致相当于

Enemy* n = new Ninja();
n->attack();
Run Code Online (Sandbox Code Playgroud)

在哪里.JAVA中的运算符更像是c ++中的 - >运算符.在这两种情况下,n都在堆上.Java只是隐藏了你的所有指针和内存管理.这就是为什么你可以对JAVA和C#中动态绑定的工作方式一无所知.