在子类中声明继承的虚函数与关键字是否之间是否有任何区别,考虑到我想要调用适合我的对象的乐趣'类型。看看评论。
#include <cstdio>
struct A{
int a;
A():a(5){}
virtual int fun(){return a+1;}
};
struct B: public A{
virtual int fun(){return a+5;} //I put virtual here
// int fun(){return a+5;} // Any difference if I put virtual before or not?
};
int main(){
B obj;
printf("%d\n", static_cast<A>(obj).fun()); // A::fun() called. Why?
printf("%d\n", static_cast<A&>(obj).fun()); // B::fun() called. As expected
printf("%d\n", static_cast<A*>(&obj)->fun()); // B::fun() called. As expected
printf("%d\n", static_cast<A>(B()).fun()); // A::fun() again. Why?
// printf("%d\n", static_cast<A&>(B()).fun()); //invalid_cast error. Why?
printf("%d\n", static_cast<A*>(&B())->fun()); //It works! B::fun() call
return 0;
}
答案 0 :(得分:4)
如果基类中的相应函数是虚拟的,则派生类中的重写函数将隐式声明为“virtual”。只要确保你有完全相同的签名,否则你可能会无意中隐藏原始功能并声明一个新功能!
在C ++ 0x中,随意使用override
说明符。
你的两个“为什么?”问题是因为切片;你正在制作A
类型的新的,复制切片的对象。请注意,在B x; static_cast<A>(x);
中,演员与说A(x)
相同。
答案 1 :(得分:3)
在派生类中重写的成员函数之前保留虚拟关键字是可选的。运行时多态性仅适用于指针或引用。