C++重载、覆盖与隐藏关系
在C++中,成员函数的重载、覆盖与隐藏是很容易混淆的概念,一定要搞清楚他们之间的关系与差别。
1、成员函数重载的特性
(1)相同的范围(即在同一个类中)。也就是意味着基类与派生类之间的成员函数不存在重载的关系;
(2)成员函数名字相同,参数不同;
(3)virtual关键字可有可无。
2、覆盖
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类中);
(2)函数的名字相同,参数也相同;
(3)基类函数必须要有virtual关键字修饰。
3、隐藏
这里的“隐藏”指的是派生类函数屏蔽了基类中与其同名的成员函数,需要与上面的两个概念区别开来:
(1)如果派生类的函数与基类的函数同名,但是参数不同,此时无论基类函数是否有virtual关键字,基类函数
都将被“隐藏”。
(2)如果派生类函数与基类函数同名,并且参数也相同,但是基类函数没有virtual关键字修饰,那么此时
基类函数将被“隐藏”。
需要注意的地方:隐藏只是导致派生类实例化的对象无法直接调用被隐藏的基类的成员函数,那么在这种情况
下,覆盖的函数其实也是不能被调用的,其实可以理解为覆盖本身也是一种隐藏,关键看我们怎么去调用
成员函数,如果是通过虚函数表的方式去调用那么就出现覆盖的特性。
当然,不管是隐藏还是覆盖,在成员函数内部还是可以调用的,例如:
#include <iostream> class CBassClass { public: virtual void FunC1(void) { std::cout << "CBassClass FunC1(void)" << std::endl; } virtual void FunC2(void) { std::cout << "CBassClass FunC2(void)" << std::endl; } virtual void FunC3(void) { std::cout << "CBassClass FunC3(void)" << std::endl; } }; class DClass :public CBassClass { public: virtual void FunC2(void) { std::cout << "DClass FunC2(void)" << std::endl; CBassClass::FunC2(); // 调用基类的成员函数 } virtual void FunC3(void) { std::cout << "DClass FunC3(void)" << std::endl; } virtual void FunC4(void) { std::cout << "DClass FunC4(void)" << std::endl; } virtual void FunC5(void) { std::cout << "DClass FunC5(void)" << std::endl; } };
这三个关系是非常容易混淆的,一定要注意他们之间的区别、不同之处。
参考博文:http://www.cnblogs.com/qlee/archive/2011/07/04/2097055.html