对虚拟函数 C++ 感到困惑
我是一个 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;
}
我的问题是为什么 Monster 或 Ninja 类中的 Attack() 函数没有被覆盖?任何帮助,甚至是链接,将不胜感激。
I'm a c++ n00b and I'm not sure if I have looked in the right places but I'm confused about this:
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;
}
My question is why isn't the attack() function in the Monster or Ninja class being overriden? Any help, even a link, would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Just do:
那就应该如你所愿。您需要使用指针才能使其工作。原因在于动态绑定的工作方式。
这个想法是,编译器根据对象的内存地址存储指向每个方法的指针。它需要指针来访问表并调用适当的函数指针。想一想,如果你想编写一个面向对象的 C 版本,你将如何提供继承和多态这样的机制?当你这样想时,这是有道理的。
我刚刚读到您要从 JAVA 转过来。在JAVA中,大部分对象都存储在堆上。这一切都只是暗示而已。
JAVA的
大致相当于
Where的. JAVA中的运算符更像是->; C++ 中的运算符。在这两种情况下,n 都在堆上。 Java 只是向您隐藏了所有指针和内存管理内容。这就是为什么您可以对动态绑定在 JAVA 和 C# 中的工作方式一无所知。
Just do:
That should do as you want. You need to use pointers for it to work. The reason lies in the way dynamic binding works.
The idea is, the compiler stores pointers to each method based on the memory address of the object. It needs the pointer to access the table and invoke the appropriate function pointer. Think about if you wanted to write an OO version of C, how would you supply such a mechanism as inheritance and polymorphism? It makes sense when you think of it that way.
I just read that you are moving over from JAVA. In JAVA, most of your objects are stored on the heap. It is all just implied.
JAVA's
is roughly equivalent to
Where the . operator in JAVA is more like the -> operator in c++. In both cases, n is on the heap. Java just hides all of the pointer and memory management stuff from you. This is why you can have blissful ignorance of the way dynamic binding works in JAVA and C#.
这与您不通过指针访问敌人有关:
This has to do with the fact that you don't access your enemies through pointers:
除非通过指针或引用访问对象,否则虚函数调用将不起作用。为了让它工作,你需要将你的敌人数组重写为
注意,你必须将所有
enemies[i].
更改为enemies[i]->< /代码>。
Unless you access an object through a pointer or reference, virtual function calls will not work. To get it to work, you'll need to re-write your enemies array as
Note that you would have to change all
enemies[i].
toenemies[i]->
.这只是对象切片 - 只会复制派生对象中的
Enemy
对象。虚函数无法发挥作用。This is just object slicing - only
Enemy
object from derived objects will be copied. Virtual functions cannot play role.这种现象称为对象切片。
The phenomenon is called object slicing.