在C++中,成员函数的重载、覆盖与隐藏是很容易混淆的概念,必定要搞清楚他们之间的关系与差异。html
一、成员函数重载的特性ios
(1)相同的范围(即在同一个类中)。也就是意味着基类与派生类之间的成员函数不存在重载的关系;函数
(2)成员函数名字相同,参数不一样;spa
(3)virtual关键字无关紧要。code
二、覆盖htm
覆盖是指派生类函数覆盖基类函数,特征是:对象
(1)不一样的范围(分别位于派生类与基类中);blog
(2)函数的名字相同,参数也相同;get
(3)基类函数必需要有virtual关键字修饰。io
三、隐藏
这里的“隐藏”指的是派生类函数屏蔽了基类中与其同名的成员函数,须要与上面的两个概念区别开来:
(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