class B {
public:
void foo(){std::cout << "test_B\n";}
};
class D: public B {
public:
void foo(){std::cout << "test_D\n";}
};
D x;
B* pb = &x;
pb->foo(); // test_B
D* pd = &x;
pd->foo(); // test_D
伪代码中两个语句的行为不一样,造成它们不同行为的原因是,non-virtual 函数如B::foo()和D::foo()都是静态绑定。意思是,由于pb被声明为一个pointer-to-B,通过pb调用的non-virtual 函数永远是B所定义的版本,即使pb指向一个”B派生之class”的对象。不过virtual函数是动态绑定,如果foo()是个virtual 函数,不论是通过pb还是pd调用foo(),都会导致调用D::foo(),因为pb和pd都是指向真正的一个类型为D的对象。
现在,如果D重新定义foo(),设计就会出现矛盾.如果D真的有必要实现出于B不同的foo(),那么”每个D都是一个B”就不为真。因此,就不应该用public形式继承B。另一方面, 如果D真的必须以public方式继承B,并且要有于B不同的foo()..这样,foo()就应该声明为virtual 函数。无论从哪方面出发都不应该重新定义继承而来的非虚函数。