标签:
看下面的两个类的声明代码:
class B { public: void mf(); //something to do }; class D : public B { public: void mf(); };
如果有下面的调用:
D x; //第一种调用 B *pB = &x; pB->mf();//调用B::mf //第二种调用 D *pD = &x; pD->mf();//调用D::mf
这两种调用的行为是不一样的,虽然从表面上看,两者都是通过对象x调用成员函数mf,凭借相同的对象。但是怎么就调用到了不同的函数呢。
造成这一两面性的原因是non-virtual函数都是静态绑定的。意思是,由于PB被声明为一个pointer-to-B,通过PB调用的non-virtual函数永远是B所定义的版本,即使PB指向了一个类型为“B派生的子类”
提示:
但是另一方面,virtual函数是动态绑定的,如果mf是一个virtual函数,不论是通过pB或者pD调用mf,都会导致调用D:mf,因为pB和pD真正指向的都是一个类型为D的对象。
所以问题就来了,如果在编程的时候,在class D中重新定义了继承自class B的non-virtual函数mf,D对象就可能展现出精神分裂的不一致行为。也就是说,当mf被调用的时候,任何一个D对象都可能表现出B或者D的行为。决定因素不在对象自身,而在于“指向该对象的指针”当初声明的类型。
提示:
References也会展现和指针难以理解的行径。
[条款36]绝不重新定义继承而来的non-virtual函数
标签:
原文地址:http://www.cnblogs.com/stemon/p/4445464.html