C++基础-重载/重写/重定义/多态
来源:互联网 发布:0.5是什么意思网络用语 编辑:程序博客网 时间:2024/05/04 20:03
1. 重载(overload)
定义
- 在一个类内,如果存在若干个同名函数,而且这些函数之间可以用形参个数或形参类型区分开来的时候(注意不能靠函数返回类型区分),这几个函数就互为重载函数
注意点
重载发生在类内,不会发生在基类和派生类之间
函数名必须相同,形参个数或类型可以不同
重载函数之间必须依靠形参个数或形参类型来进行区分,不能依靠返回类型。
- 如果两个函数同名同参,但返回类型不同,编译器会因为二义性而报错
重载调用:通过类对象调用重载函数时,编译器通过传递的实参个数或类型去匹配相应的函数,而不会发生歧义。
- 体现了重载的作用:可以使用若干个同名函数
虚函数和普通函数之间也可以重载
2. 重写(override,覆盖)
定义
- 重写也称为覆盖,重写了一个方法以实现不同功能。一般用于子类继承父类时,重写父类中的方法。函数特征相同,具体实现不同。
注意点
重写只能出现在基类和派生类之间,当
- [1] 基类和派生类之间存在同名函数
- [2] 返回类型、形参个数和类型完全相同
- [3] 基类中的该函数必须是virtual(派生类中virtual可有可无)
则派生类中的该函数覆盖掉基类中的该函数,此性质用来实现多态
重写函数的访问修饰符可以不同,即使virtual是private的,派生类中改为public或protected也可以
3. 重定义(redefining,隐藏)
定义
- 重定义也称为隐藏,派生类对基类成员函数重新定义,即派生类定义了某个函数,该函数与基类中函数同名
注意点
重定义也只能出现在基类和派生类之间,当
- [1] 基类和派生类之间存在同名函数
- [2] 无论返回类型、形参个数和类型是否相同
则基类中的同名函数都会被隐藏
- 如果基类中该函数被重载,则重载函数都会被隐藏,包括虚函数
如果返回类型、形参个数和类型均相同,且基类中为virtual函数,则属于重写
如果要访问基类的该函数,需要在函数名前加上作用域操作符
4. 多态(polymorphism)
定义
多态是面向对象思想的精髓所在,使用多态是为了避免在父类中大量重载而引起代码臃肿和难于维护
关于多态,一种不严谨的说法是:继承是子类使用父类的方法,多态是父类使用子类的方法。
多态的分类
多态可以分为两类:静态多态性 + 动态多态性
[1] 静态多态性:又称编译时的多态性,静态多态性是通过函数的重载实现的
- 函数重载和运算符重载实现的多态性属于静态多态性,在程序编译时就能决定调用哪个函数
[2] 动态多态性:又称运行时的多态性,动态多态性是通过虚函数实现的。
- 程序运行过程中才动态地确定操作所针对的对象
注意点
虚函数存在的唯一目的就是为了实现多态,成员函数要以多态的形式来执行,那么必须满足
- (1) 基类中这些成员函数为虚函数,并必须实现
- (2) 派生类中这些成员函数必须被重写(同名 + 同返回同形参个数和类型 + 基类中为virtual)
- (3) 将派生类的对象赋给基类的指针变量或引用,可用基类的指针或引用调用派生类的方法
实现多态,上述三个条件必须完全满足,虚函数的特性才能完全发挥出来,也才能实现多态。
不是多态的例子
[1] 派生类和基类都是虚函数,派生类中与基类函数同名,形参个数或类型与基类中不同,这种情况属于隐藏,不会报错
- 如果形参的个数和类型相同,返回类型也必须相同,否则编译会报错,因为返回类型发生了冲突,隐藏发生错误
[2] 基类中是虚函数,派生类中不是虚函数,派生类中与基类函数同名,返回类型或形参个数或类型与基类不同,这种情况也属于隐藏,如果返回类型、形参个数和类型均相同,这种情况属于重写,不会报错
[3] 基类中不是虚函数,派生类中是虚函数,或基类派生类中均不是虚函数,派生类中与基类函数同名,这种情况属于隐藏,同样也不会报错
附:实例说明
- [1] 重载,重写,重定义
#include <iostream>using namespace std;class BasicClass{ private: int a; public: //函数重载实例 void overloadFunc(int k) { cout<<"overloadFunc single parameter:"<<k<<endl; } void overloadFunc(int k,int t) { cout<<"overloadFunc two parameters:"<<" k:"<<k<<" t:"<<t<<endl; } virtual void overrideFunc() { cout<<"override fun from basic class!"<<endl; }};class DeriveClass : public BasicClass{ private: public: //重定义:隐藏 void overloadFunc(int k) { cout<<"redefine overloadFunc from derived Class!"<<endl; } //重写 void overrideFunc() { cout<<"override from derived class!"<<endl; }};int main(){ BasicClass a; DeriveClass b; //重载调用 cout<<"重载调用"<<endl; a.overloadFunc(1); a.overloadFunc(1,2); //根据形参来区分调用哪个函数 //重写 cout<<endl; cout<<"重写-该性质可实现多态"<<endl; b.overrideFunc(); a.overrideFunc(); //隐藏 cout<<endl; cout<<"重定义/隐藏"<<endl; a.overloadFunc(1); b.BasicClass::overloadFunc(1); //重定义时可以通过作用域操作符访问基类函数 b.overloadFunc(1); return 0;}
- [2] 多态
#include <iostream>using namespace std;class A{ public: virtual void test(int a) { cout<<"basic class A: "<<a<<endl; }};class B: public A{ public: void test(int b) //重写-覆盖 { cout<<"derived class B: "<<b<<endl; }};class C: public A{ public: void test(int c) { cout<<"derived class C: "<<c<<endl; }};int main(){ A *a0; //指针 B b; C c; A &a1 = b; //引用 A &a2 = c; a0 = &b; a0->test(2); //调用类B的test函数 a0 = &c; a0->test(3); //调用类C的test函数 a1.test(4); //调用类B的test函数 a2.test(5); //调用类C的test函数 return 0;}
Acknowledgements:
http://www.cnblogs.com/DannyShi/p/4593735.html
http://www.cnblogs.com/liangning/p/3968151.html
http://blog.csdn.net/loverooney/article/details/38307523
2017.09.26
- C++基础-重载/重写/重定义/多态
- 重载、重写、重定义
- 重写,重载,重定义
- 重写重载重定义
- 重载重写重定义
- 重写 重载 重定义
- 重载重写重定义
- 重写,重载,重定义
- 重载,重写,重定义
- 重载重写重定义
- 重载、重写与重定义
- 关于重载、重写、重定义
- c++重写、重载、重定义
- 重载重写与重定义
- C++重载,重写,重定义
- C++重载、重写、重定义
- C++重载重写重定义
- C++ 重载、重写、重定义
- linux权限1
- 结构体分级排序
- HDU1205最多糖果(隔板)构造最大空间
- SQL Server 触发器
- HDOJ2013
- C++基础-重载/重写/重定义/多态
- 基于Http协议的Android网络编程
- 递归求解从数组中取出n个元素的所有组合
- traceroute 基本教程
- 最小的K个数java实现
- ACM 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 B. Train Seats Reservation
- HDOJ2014
- String使用equals方法和==分别比较的是什么?(转)
- HDOJ2015