【发布时间】:2014-01-20 17:33:10
【问题描述】:
我有这条鳕鱼:
class First{
public:
virtual void print(){cout<<"First";}
};
class Second : public First {
public:
virtual void print(){cout<<"Second";}
};
class Third : public Second{
public:
void print(){cout<<"Third";}
int main(){
Third ob;
ob.print();
Second& sec=ob;
sec.print();
First& frs=ob;
frs.print();
}
一切都如我所料,所有 3 打印:“第三”。
现在因为我的代码太多了,基本都是一样的,稍加改动我会在文中讨论。
现在我从 First 中的 print 中删除 virtual 并打印出:“Third Third First”,正如我所料。
第三次,我将虚拟放回 First,但我将其从 Second 中删除。现在它打印: “三三三”。嗯,这不是我所期望的。假设当使用引用 First 时,它看到函数是虚拟的,然后检查对象并调用 Third 的方法,但是当使用引用 Second 时,它看到函数不是虚拟的,为什么它仍然调用 Third 的打印?
【问题讨论】:
-
这是因为您使用的是第三个对象的引用。即使您强制转换类型,运行时 vtable 仍将其视为第三
-
Second中的函数是隐式虚函数,因为它与First中的函数具有相同的签名。 -
请注意,将
Second中的print标记为final会在出现Third时给您一个明显的错误。 -
@dyp 如果您想发表您的评论作为答案,我会接受。
-
@StefanStojkovski Mike Seymour 的回答基本相同(当您知道覆盖 == 基类函数是虚拟的并且具有相同/协变签名时)。
标签: c++ class inheritance virtual