《Effective C++》学习笔记——条款36


六、继承与面向对象设计


条款36、绝不重新定义继承而来的 non-virtual 函数
Rule 36. Never redefine an inherited non-virtual function.





如果在基类中有一个public函数,创建一个派生类指针指向基类对象调用这个函数,然后再创建一个基类指针指向这个对象调用这个函数,结果应该是一样的吗?
不一样! 因为在派生类中,如果重新定义基类的函数,将会遮掩基类的相应函数,通过派生类调用该函数,永远是派生类的版本,而非基类的版本。

class B {
public:
    void mf();
    ...
};
class D : public B  {
public:
    void mf();    // 遮掩了基类B的mf函数(可详见条款33)
    ...
};

D x;
B* pB = &x;
D* pD = &x;
pB->mf();    // 调用 B::mf
pD->mf();    // 调用 D::mf

造成这样现象的原因是,non-virtual函数如B::mf 和 D::mf 都是静态绑定。
但,virtual函数就是 动态绑定,所以,它们不会出现这个问题。

在之前的条款32中,也已经说过,public继承 意味着 is-a 关系。条款34中也描述了为什么在 class 内声明一个 non-virtual 函数会为该class建立起一个不变性。施之于此例,则表现为:

  • 适用于B对象的每一件事,也适用于D对象,因为每个D对象都是一个B对象。
  • B类的派生类一定会继承mf的接口和实现,因为mf是B的一个non-virtual函数。

所以,据上所述,任何情况下都不该重新定义一个继承而来的non-virtual函数。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值