a) 重载(overload)。

重载这个名词本身比较简单,函数一共只有三个要素:函数名、形参、返回值。重载的要素是很明确的:函数重名,形参不同(个数或者类型不同都可以)。与返回值无关。但是一定请不要忘记重载另一个非常重要的要素:同一个作用域内才发生重载

[重载与继承]

关于这二者的关系有两条准则(仔细看,其实就是一条):

如果派生类重定义了重载成员,则通过派生类型只能访问派生类中重定义的那些成员。

如果派生类想通过自身类型使用所有的重载版本,则派生类必须要么重定义所有的重载版本,要么一个也不重定义。

b) 覆盖(override)

同一个作用域内满足一定条件会发生重载。那不同的作用域内呢?只满足一个条件:重名,就一定发生覆盖!(不需要其他的要素。)而且一定是:在较小的那个作用域中,覆盖作用域大的。比如:局部变量一定是覆盖全局变量,全局变量不可见。但涉及到继承,也是一样:在派生类作用域中派生类成员将屏蔽基类成员。即使函数原型不同,基类成员也会被屏蔽。(参见《C++ Primer》中文版第四版P499)。这个实际上也是名字查找的原则之一(参见这篇文章)。

而且这里隐含着另一层意思:基类成员并不是消失,也不是被取代,而只是被屏蔽而不能被调用!所以其实我不喜欢用覆盖这个词,不如用“隐藏”或者“屏蔽”更能表明状况。

而如果派生类中的函数与基类函数原型完全相同,则会发生重定义!这个时候就不是简单意义上的覆盖了,基类函数将在派生类中被取代,也就是消失!

=================================================

下面是《C++ Primer》书中的经典例子。请读者结合以上问题介绍进行理解。

class Base
{
public
:
    
virtual int
fcn();
};

class Derived1 : public
Base
{
public
:
    
//hides Base::fcn(), this fcn(int) is not virtual

    int fcn(int);
    
//Derived1 inherits definition of Base::fcn()

};

class Derived2 : public
Derived1
{
public
:
    
int fcn(int);//nonvirtual function hides Derived1::fcn(int)

    int fcn();//redefine virtual Base::fcn()
};



通过 Wiz 发布


posted on 2011-05-11 22:55  微型葡萄  阅读(475)  评论(0编辑  收藏  举报