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()函数不被覆盖?任何帮助,甚至链接,将不胜感激.
做就是了:
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#中动态绑定的工作方式一无所知.