条款21 重载与重写并不相同
重载与重写其实没有关系,只是在使用过程中,由于某些函数的命名的问题不注意,让我们产生了不计其数的bug
当位于同一个作用域中的两个或者更多个函数名字相同但是参数数目不同,或者数目相同但参数类型不一样的函数相互之间就会发生重载。即函数在调用的时候,会按照参数列表优先选择最匹配的函数进行调用;—— 这样就形成了,同一个函数名称(操作方法),按照其传进的参数不同(原料不同), 得到不同的函数的调用(结果不同)——这就是重载
重写:当派生类函数和基类的虚函数含有相同名字和参数列表的时候,基类调用的时候,调用的是基类的虚函数,子类调用的时候调用的是子类的虚函数,发生重写,(此处的调用指的是指针或者引用的调用,因为只有这样才会有动态行为绑定)——这样就是重写,同一个函数名称(操作方法),由类层次结构中,不同的类来执行(执行操作的人不同),导致了不同的函数的调用(结果不同)——这就是重写。——这个实现的是:在基类约定的接口不变的情况下,通过子类实现虚函数改变具体类的具体实现。
举例:
1: class Base
2: {
3: public:
4: //...
5: virtual int f ( int );
6: void f( Base *);
7: };
8:
9: class D:: public Base
10: {
11: public:
12: //...
13: int f(int );
14: int f( B *);
15: };
在上面的例子中,可以看出
D::f( int ) 与 基类的Base::f( int ) 形成重写会有动态绑定。 此时D::f( int ) 与 D::f( B *) 之间形成重载关系。
Base::f( int ) 与 Base::f(Base*) 两者之间形成重载关系,
注意,这里类的设计者有一个纠结的关系,就是D::f( int ) 与 基类的Base::f( int ) 他们是相互重写的,代码能够动态调用绑定,类层次结构中调用会有不同的效果,但是,又分别于同层次的函数发生重载,不得不说这是一个很蹩脚的设计。