考虑以下源代码。我有两个类CBar和CFoo。 CFoo继承自CBar。此源代码的输出是
Bar
Foo
Bar
我在期待
Bar
Foo
Foo
我哪里出错了? 我在想的是因为CFoo对象有一个Speak函数可以覆盖CBar说话函数。当我从CFoo对象上的CBar函数调用Speak()函数时,将执行CFoo Speak函数。但这种假设似乎是错误的。
class CBar
{
public:
void Speak() {
printf(" Bar \n");
}
void DoStuff() {
this->Speak();
}
};
class Cfoo : public CBar
{
public:
void Speak() {
printf(" Foo \n");
}
void DoStuff() {
CBar::DoStuff();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CBar b;
b.Speak();
Cfoo f;
f.Speak();
f.DoStuff();
return 0;
}
答案 0 :(得分:3)
在C ++中,您需要使用virtual
来启用多态。否则,Speak()
中所有CFoo
正在Speak()
隐藏CBar
。
class CBar
{
public:
virtual void Speak() { // Note virtual keyword
printf(" Bar \n");
}
void DoStuff() {
this->Speak();
}
};
class Cfoo : public CBar
{
public:
void Speak() { // Overrides the virtual method Speak()
printf(" Foo \n");
}
void DoStuff() { // Hides CBar::DoStuff() method
CBar::DoStuff();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CBar b;
b.Speak();
// Speak() is a virtual function, so calling Speak() on a CFoo or
// a CBar pointer will call the most derived implementation of Speak().
Cfoo f;
f.Speak();
/* My example */
// Since CFoo "is-a" CBar, this conversion is safe.
CBar* bar = &f;
// Since Speak() is a virtual function, this will call CFoo's implementation
// of Speak(), not CBar's.
bar->Speak();
/* End example */
// Because CBar::DoStuff() is hidden, this calls CFoo::DoStuff() instead.
f.DoStuff();
return 0;
}
答案 1 :(得分:3)
Speak
不是多态函数。
也就是说,因为它没有标记为virtual
,所以对它的任何调用都是静态确定的。因此,在CBar
中,this->Speak();
将始终引用CBar::Speak
。
如果你使虚函数成功,将根据动态类型选择对函数的调用,而不是静态类型,以及你期望的调用。