前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >1小时精通c++面向对象编程

1小时精通c++面向对象编程

作者头像
mathor
发布2018-07-24 15:06:59
7930
发布2018-07-24 15:06:59
举报
文章被收录于专栏:mathormathor

五、多态性和虚函数

5.1 多态性

发出同样的消息被不同类型的对象接受导致完全不同的行为

多态可分为:静态多态性与动态多态性(必须存在于继承的环境之中)

5.1.1 函数重载

在类中,构造函数可以重载,普通成员函数也可以重载

5.1.2 示例

图5-1 构造函数重载

5.1.3 哪些运算符可以重载?

图5-2 运算符重载

5.1.4 重载为类的成员函数

重载一元运算符,不再显式说明参数

重载二元运算符,只显式说明一个参数;该参数为操作数的右操作数,左操作数由this指针(指向调用该成员函数的对象)提供

重载为成员函数时,隐含了一个参数(this指针)

5.1.5 示例

图5-3 重载成员函数

5.1.6 重载为友元函数

重载为友元函数时,没有隐含的参数this指针,即不改变原有运算符的语法结构

下列运算符不能重载为友元函数:=、()、[]、->

重载为友元函数的运算符重载函数的格式:friend <类型说明符> operator <运算符>(<参数表>)

5.1.7 示例

图5-4 重载友元函数

5.2 静态束定(静态联编)

静态联编是指联编工作在编译阶段完成的,这种联编过程是在程序运行之前完成的,又称为早期联编。要实现静态联编,在编译阶段就必须确定程序中的操作调用(如函数调用)与执行该操作代码间的关系,确定这种关系称为束定,在编译时的束定称为静态束定。静态联编对函数的选择是基于指向对象的指针或者引用的类型。其优点是效率高,但灵活性差

5.2.1 静态联编示例

图5-5 静态联编

从示例可以看出,通过对象指针进行的普通成员函数的调用,仅仅与指针的类型有关,而与此刻指针正指向什么对象无关。要想实现当指针指向不同对象时执行不同的操作,就必须将基类中相应的成员函数定义为虚函数,进行动态联编

5.3 动态束定(动态联编)

动态联编是指联编在程序运行时动态地进行,根据当时的情况来确定调用哪个同名函数,实际上是在运行时虚函数的实现。这种联编又称为晚期联编,或动态束定。动态联编对成员函数的选择是基于对象的类型,针对不同的对象类型将做出不同的编译结果。C++中一般情况下的联编是静态联编,但是当涉及到多态性和虚函数时应该使用动态联编。动态联编的优点是灵活性强,但效率低

实现动态联编需要同时满足以下三个条件:

1必须把动态联编的行为定义为类的虚函数

2类之间应满足子类型关系,通常表现为一个类从另一个类公有派生而来

3必须先使用基类指针指向子类型的对象,然后直接或者间接使用基类指针调用虚函数

5.3.1 动态联编示例

图5-6 动态联编示例

5.4 虚函数

虚函数是动态束定的基础

虚函数是非static成员函数

格式:virtual<类型说明符> <函数名>(<参数表>)

若类中一成员函数被说明为虚函数,则该成员函数在派生类中可能有不同的实现。当使用该成员函数操作指针或引用所标识的对象时,对该成员函数调用可采用动态束定方式

动态束定只能通过指针或引用标识对象来操作虚函数。如果采用一般类型的标识对象来操作虚函数,则将采用静态束定方式调用虚函数

5.4.1 示例

图5-7 虚函数与动态联编

解释一下上面的程序,B从A公有继承,B是A的子类型,B中的act1()为虚函数,b.act2()调用A中的act2(),进一步调用act1(),产生动态束定,运行时选择B::act1()

5.5 纯虚函数

在基类中不能为虚函数给出一个有意义的实现时,可将其声明为纯虚函数,其实现留待派生类完成

5.5.1 纯虚函数定义格式

图5-8 纯虚函数定义格式

5.5.1 示例

图5-9 纯虚函数

5.6 抽象类

带有纯虚函数的类称为抽象类

抽象类只能作为基类使用,其纯虚函数的实现由派生类给出;但派生类仍可不给出纯虚函数的定义,继续作为抽象类存在

抽象类不能定义对象,一般将该类的构造函数说明为保护的访问控制权限

在成员函数内可以调用纯虚函数,但在构造函数或析构函数内不能调用纯虚函数(纯虚函数没有实现代码)

5.6.1 抽象类的作用

1用作基类:在一个继承层次结构中,提供一个公共的根,并基于抽象类的操作设计出对抽象类所描述的一类对象进行操作的公共接口,其完整的实现由派生类完成

2用作指针或引用的基类型:保证进入继承层次的每个类都具有(提供)纯虚函数所要求的行为

图5-10 纯虚函数调用方法

5.6.2 示例

图5-11 纯虚函数

图5-12 纯虚函数(续)

图5-13 纯虚函数(续)

5.6.3 说明

图5-14 抽象类

5.7 虚析构函数

在析构函数前加关键字virtual进行说明,则该析构函数称为虚析构函数

如果一个类的析构函数被说明为虚析构函数,则它的派生类中的析构函数也是虚析构函数,不管它是否使用了关键字virtual进行说明

子类型化要求析构函数被声明为虚函数,尤其是在析构函数要完成一些有意义的工作时,构造函数不能被声明为虚函数

目的:使用delete运算符删除一个对象时,能保证析构函数被正确地执行

图5-15 虚析构函数格式

5.7.1 示例

图5-16 虚析构函数

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-01-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档