码迷,mamicode.com
首页 > 其他好文 > 详细

条款37: 决不要重新定义继承而来的非虚函数

时间:2014-08-20 16:01:52      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   div   代码   amp   log   sp   

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

class D: public B { ... };

甚至对B,D或mf一无所知,也可以定义一个类型D的对象x,

D x;                          // x是类型D的一个对象

那么,如果发现这么做:

B *pB = &x;                   // 得到x的指针

pB->mf();                     // 通过指针调用mf

和下面这么做的执行行为不一样:

D *pD = &x;                   // 得到x的指针

pD->mf();                     // 通过指针调用mf

你一定就会感到很惊奇。

如果mf是非虚函数而D又定义了自己的mf版本,行为就不会相同:

class D: public B {
public:
  void mf();                  // 隐藏了B::mf; 参见条款50

  ...

};


pB->mf();                     // 调用B::mf

pD->mf();                     // 调用D::mf

名字查找与继承:(函数调用步骤)

假设调用p->mem()

1.首先确定p的静态类型

2.在p的静态类型对应的类中查找,如果找不到,则依次在直接基类中不断查找直至到达继承链的顶端,如果找遍了该类及其基类仍然找不到,编译器将报错

3.一旦找到mem,就进行常规的类型检查,以确认对于当前找到的mem,本次调用是否合法

4.假设调用合法,则编译器根据调用的是否是虚函数而产生不同的代码:

如果mem是虚函数且我们是通过引用或指针进行的调用,则编译器产生的代码将在运行时确定到底运行该虚函数的哪个版本,依据是对象的动态类型;

反之,则编译器将产生一个常规函数调用,即静态绑定

 

条款37: 决不要重新定义继承而来的非虚函数,布布扣,bubuko.com

条款37: 决不要重新定义继承而来的非虚函数

标签:style   blog   color   div   代码   amp   log   sp   

原文地址:http://www.cnblogs.com/ljygoodgoodstudydaydayup/p/3924468.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!