C++中的多态(一)
来源:互联网 发布:免费听小说的软件 编辑:程序博客网 时间:2024/05/22 10:43
多态:一词最初来源于希腊语,意思是具有多种形式或形态的情形。通俗的讲,水在不同的温度下所呈现的不同的状态,比如:水在零摄氏度以下是固态的,在0~100度之间是液态的,在100度以上是气态的。
在C++语言中多态有着更广泛的含义
【静态多态】:
int Add(int a, int b){ return a + b;}float Add(float a, float b){ return a + b;}int main(){ cout << Add(30, 20) << endl; cout << Add(11.10f, 22.20f) << endl; return 0;}
运行结果:
静态多态:编译器在编译期间完成的,编译器根据函数实参的类型(可能会进行隐式类型转换),可推断出要调用那个函数,如果有对应的函数就调用该函数,否则出现编译错误。
【动态多态】:
动态绑定:在程序执行期间(非编译期)判断所引用对象的实际类型,根据其实际类型调用相应的方法。
使用virtual关键字修饰类的成员函数时,指明该函数为虚函数,派生类需要重新实现,编译器将实现动态绑定。
下来咱们举一个简单的例子:
class WashRoom//修建厕所{public: void GoToManWashRoom() { cout << "Man-->Please Left" << endl; } void GoToWomanWashRoom() { cout << "Woman-->Please Right" << endl; }};class Person//人{public: virtual void GoToWashRoom(WashRoom & _washRoom) = 0;};class Man :public Person//男士往左{public: virtual void GoToWashRoom(WashRoom & washRoom) { washRoom.GoToManWashRoom(); }};class Woman :public Person//女士朝右{public: virtual void GoToWashRoom(WashRoom & washRoom) { washRoom.GoToWomanWashRoom(); }};void FunTest(){ WashRoom washRoom;//找到厕所 //来了十个人,性别随机 for (int iIdx = 1; iIdx <= 10; ++iIdx) { Person* pPerson;//一个人 int iPerson = rand() % iIdx;//性别随机 if (iPerson & 0x01) pPerson = new Man;//若为男士 else pPerson = new Woman; //若为女士 pPerson->GoToWashRoom(washRoom);//选择适当方向 delete pPerson;//销毁对象 pPerson = NULL; Sleep(1000); }}int main(){ FunTest(); return 0;}
运行结果:
【动态绑定条件】
1、通过基类类型的引用或者指针调用虚函数
2、必须是虚函数(派生类一定要重写基类的虚函数)
class Base{public: virtual void FunTest1(int _iTest) { cout << "Base::FunTest1()" << endl; } void FunTest2(int _iTest) { cout << "Base::FunTest2()" << endl; } virtual void FunTest3(int _iTest1) { cout << "Base::FunTest3()" << endl; } virtual void FunTest4(int _iTest) { cout << "Base::FunTest4()" << endl; }};class Derived :public Base{public: virtual void FunTest1(int _iTest) { cout << "Derived::FunTest1()" << endl; } virtual void FunTest2(int _iTest) { cout << "Derived::FunTest2()" << endl; } void FunTest3(int _iTest1) { cout << "Derived::FunTest3()" << endl; } virtual void FunTest4(int _iTest1, int _iTest2) { cout << "Derived::FunTest4()" << endl; }};int main(){ Base* pBase = new Derived; pBase->FunTest1(0); pBase->FunTest2(0); pBase->FunTest3(0); pBase->FunTest4(0); pBase->FunTest4(0); return 0;}
运行结果:
继承体系同名成员函数的关系:
那些成员函数不能定义成虚函数?
(1).友元函数
(2).构造函数
(3).静态成员函数(static)
(4).内联函数(inline)
注:
(1)最好将基类中的析构函数给成virtual;
(2)最好不要使基类的运算符重载给成virtual
总结:
1、派生类重写基类的虚函数实现多态,要求函数名、参数列表、返回值完全相同(协变除外)。
2、基类中定义了虚函数,在派生类中该函数始终保持虚函数的特性。
3、只有类的非静态成员函数才能定义为虚函数,静态成员函数不能定义为虚函数。
4、如果在类外定义虚函数,只能在声明函数时加virtual关键字,定义时不用加。
5、构造函数不能定义为虚函数,虽然可以将operator=定义为虚函数,但最好不要这么做,使用时容易混淆。
6、不要在构造函数和析构函数中调用虚函数,在构造函数和析构函数中,对象是不完整的,可能会出现未定义的行为。
7、最好将基类的析构函数声明为虚函数。(析构函数比较特殊,因为派生类的析构函数跟基类的析构函数名称不一样,但是构成覆盖,这里编译器做了特殊处理)
8、虚表是所有类对象实例共用的
- C#中的异常处理(一)
- C#中的异常处理(一)
- C#中的异常处理(简单)一
- 理解C语言中的指针(一)
- [C++] Vector 中的基本用法(一)
- GNU C 中的__attribute__ (一)
- C语言中的一些关键字(一)
- C语言中的指针(一)
- c语言中的输入输出(一)
- MFC中的C++(一)
- Java中的多态学习(一)
- Java中的多态(一)
- C++中的多态(一)
- 浅谈.Net(C#)中的线程同步(一)
- C中的文件与IO操作(一)
- C++.net中的常见问题一(关于数组)
- C中的main函数是个另类(一)
- C#.NET中的线程同步类(一)
- Py数
- 虚幻4键盘鼠标控制输入事件操作笔记
- 3.标识符_unicode和GBK各种编码间关系
- Multiply
- Linux内核 TCP/IP、Socket参数调优
- C++中的多态(一)
- 让低版本的IE浏览器支持HTML5
- 我国将实行“渐进式延迟退休”!退休后的养老金还会涨吗?
- 线程练习题
- 感知机
- 欢迎使用CSDN-markdown编辑器
- log4j的日志级别以及相关配置详解
- 输入数据异常处理
- Shader的学习