c++重载、覆盖、隐藏
2016-07-27 21:20
197 查看
重载(overload)是指函数不同的参数列表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数。在同一可访问域内(注意同一访问域,基类和派生类不属于同一访问域)被声明的几个具有不同参数列表(参数类型、个数、顺序)的同名函数,程序会根据不同的参数列来确定具体调用哪个函数。对于重载函数的调用,在编译期间就已经确定,是静态的,它们的地址在编译期间就绑定好了,与多态无关。注意,重载不关心函数的返回值类型。
成员函数被重载的特征:
(1) 相同的范围(在同一个类中)
(2)函数名字相同
(3)参数不同
(4)virtual关键字可有可无
覆盖(override)是指派生类中存在重新定义基类的函数,其函数名/参数列/返回值类型必须同基类中对应被覆盖的函数严格一致,覆盖函数和被覆盖函数只有函数体不同。当子类重新定义了父类的虚函数后,父类指针会进行动态绑定。
覆盖的特征如下:
(1)不同的范围(分别位于基类和派生类中[/u])
(2)函数名、参数列、返回值严格一致
(3)基类函数必须有virtual关键字
隐藏(hide)是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类函数与基类函数同名但是参数不同,则无论有无virtual关键字,基类函数都将被隐藏
(2)如果派生类函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字,此时基类的函数被隐藏
注:在不同域中,编译器只看函数名,不看其它东西
关于隐藏和重载有一个很好的例子:
运行结果就是:
helloWorld
CB::f()
CD::f(int)
形象一点就是这个Java和C++就有区别了,感觉Java的比较合常理啊,我爸爸有辆大奔,我自己有辆宝马,我爸爸说,我的大奔就是你的大奔,那我当然既能开大奔,又能开宝马了,凭什么只能开宝马呢?
另外JAVA中private函数不能重载,比如:
运行结果:
helloWorld
CB::f()
CB::f()
CB::f()
而在c++中,直接重载了!
运行结果:
CB::f()
CD::f()
CD::f()
不过说实在的,我觉得没必要这么转牛角尖,为啥要覆盖私有成员函数呢?派生类应该根本见不到基类的私有成员接口,否则破坏了封装性
成员函数被重载的特征:
(1) 相同的范围(在同一个类中)
(2)函数名字相同
(3)参数不同
(4)virtual关键字可有可无
覆盖(override)是指派生类中存在重新定义基类的函数,其函数名/参数列/返回值类型必须同基类中对应被覆盖的函数严格一致,覆盖函数和被覆盖函数只有函数体不同。当子类重新定义了父类的虚函数后,父类指针会进行动态绑定。
覆盖的特征如下:
(1)不同的范围(分别位于基类和派生类中[/u])
(2)函数名、参数列、返回值严格一致
(3)基类函数必须有virtual关键字
隐藏(hide)是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类函数与基类函数同名但是参数不同,则无论有无virtual关键字,基类函数都将被隐藏
(2)如果派生类函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字,此时基类的函数被隐藏
注:在不同域中,编译器只看函数名,不看其它东西
关于隐藏和重载有一个很好的例子:
class CB { public void f(){ System.out.println("CB::f()"); } } class CD extends CB { public void f(int a){ System.out.println("CD::f(int)"); } } public class MyTest { public static void main(String args[]) { System.out.println("helloWorld"); CD test = new CD(); test.f(); test.f(1); } }
运行结果就是:
helloWorld
CB::f()
CD::f(int)
形象一点就是这个Java和C++就有区别了,感觉Java的比较合常理啊,我爸爸有辆大奔,我自己有辆宝马,我爸爸说,我的大奔就是你的大奔,那我当然既能开大奔,又能开宝马了,凭什么只能开宝马呢?
另外JAVA中private函数不能重载,比如:
class CB { private void f(){ System.out.println("CB::f()"); } public void ff(){ f(); } } class CD extends CB { public void f(){ System.out.println("CD::f()"); } } public class MyTest { public static void main(String args[]) { System.out.println("helloWorld"); CD cd = new CD(); CB cb = new CB(); CB cbd = new CD(); cd.ff(); cb.ff(); cbd.ff(); } }
运行结果:
helloWorld
CB::f()
CB::f()
CB::f()
而在c++中,直接重载了!
class CB { private: virtual void f(){ cout<< "CB::f()" << endl; } public: void ff(){ f(); } }; class CD : public CB { private: void f(){ cout<< "CD::f()" << endl; } }; int _tmain(int argc, _TCHAR* argv[]) { CD test; CB test2; CB * cb = &test2; CD * cd = &test; CB * cbd = &test; cb->ff(); cd->ff(); cbd->ff(); return 0; }
运行结果:
CB::f()
CD::f()
CD::f()
不过说实在的,我觉得没必要这么转牛角尖,为啥要覆盖私有成员函数呢?派生类应该根本见不到基类的私有成员接口,否则破坏了封装性
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- C#与.net高级编程 C#的多态介绍
- C#中面向对象编程机制之多态学习笔记
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C#中的多态深入理解
- C#中多态、重载、重写区别分析
- 设计引导--一个鸭子游戏引发的设计理念(多态,继承,抽象,接口,策略者模式)
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结