36. Never redifine an inherited non-virtual function

绝不重新定义继承而来的non-virtual函数

class  B
{
public:
	void mf();
	...
};

class D : public B
{
	...
}

有以下调用:

D x;
b
B* pB = &x;
pB->mf(); // line1

D* pD = &x;
pD->mf(); // line2

line1、line2都是调用的是=B::mf()

如果Class D重新定义了mf():

class D : public B
{
public:
	void mf();
	...
}

则line1调用B::mf(), 而line2调用D::mf()。原因是non-virtual函数B::mf()D::mf()都是静态绑定

另一方面,virtual函数却是动态绑定,所以它们不受这个问题之苦。如果mf是个virtual函数,不论是通过pB或者pD调用mf,都会导致调用D::mf,因为pB和pD真正指的都是类型为D的对象。

如果正在编写的class D重新定义继承自class B的non-virtual函数mf,D对象很可能展现出精神分裂的不一致行为。更明确的说,任何一个D对象都可能表现出B或D的行为;决定因素不在对象自身,而在于"指向该对象之指针"当初的声明类型。References也会展现和指针一样难以理解的行径。

现在,如果D重新定义mf,你的设计便会出现矛盾


如果D真有必要实现出与B不同的mf,并且如果每一个B对象-不管多么特化=真的必须使用B所提供的mf实现码,那么"每一个D都是B"就不为真。既然如此D就不应该以public形式继承B。


另一方面,如果D真的必须以public方式继承B,并且如果D真有需要实现出于B不同的mf,那么mf就无法为B反映出"不变性凌驾特异性"的性质。既然这样mf应该声明为virtual函数。


最后,如果每个D真的是一个B,并且如果mf真的为B反映出"不变性凌驾特异性"的性质,那么D便不需要重新定义mf,并且它也不应该尝试这样做。

请记住:

决定不要重新定义继承而来的non-virtual函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值