23、C++多态(虚函数 纯虚函数 抽象类 )

C++中多态

一、多态有狭义和广义之说

狭义上:为对象的类型变化,行为随之变化

广义上:程序中的标识符(对象,宏 函数 模板)的不同。

有静态多态和动态多态。这里主要讨论的主要是动态多态。

静态多态:预处理时期和编译时期的多态,主要通过函数重载、模板、宏定义来表现。

动态多态:运行时时期的多态。随着程序的运行,不同的对象,行为也会改变。

因为C++是一种强类型语言,变量一旦声明,其类型是不会改变的,

所以在C++中实现多态不能直接用对象,而是用指向对象的指针或引用

,并且对象的类型在定义时也有一定要求。具有动态特征的实体是对象。

二、动态多态

实现方式:

1、将与多态行为相关的函数,在基类中声明为虚函数

2、派生类改写基类的虚函数

3、通过基类型的指针(或者引用),调用虚函数

注:实现动态多态依靠的主要是虚函数。

虚函数的声明:(只能是成员函数)

比普通函数前面多一个virtual

virtual 返回类型 函数名(形参表)

{

函数体

}

三、虚函数在派生类中的处理

1、不做任何修改,像普通函数一样直接继承,接受基类中此函数的默认实现。

2、改写此虚函数。

改写规则:如果要在派生中类重新改写此函数,就必须重新声明

1、函数名 参数列表 完全相同

2、与基类的虚函数同为const或者非const成员函数

3、返回值类型相同,或者是存在继承关系类型的指针 或 引用 

如:基类中返回 A * 派生类中返回 B  *,B派生于A类。

4、派生类重新声明改写虚函数时,virtual可加可不加,一个成员函数

只要在基类中声明为虚函数,则在其后所有的派生类中都是虚函数。

四、纯虚函数与抽象类

1、纯虚函数

纯虚函数是一个在基类中说明的虚函数,它在该基类中没有定义,只有声明。

但要求在它的派生类中根据需要对它进行定义,或仍然说明为纯虚函数。

作用:在基类中为其派生类保留一个函数的名字,以便派生类根据需要对它进

行重新定义。

纯虚函数声明语法:

virtual 返回类型 函数名(参数表)=0 ;

2、抽象类

如果一个类至少拥有一个纯虚函数,那么就是抽象类。

同时也可以有其它成员,如数据成员,普通成员函数。

性质:

a、抽象类只能用作其他类的基类,不能建立抽象类对象实例。

b、抽象类不能用作参数类型、函数返回类型、或显示转换的类型,

但可以声明指向抽象类的指针变量、此指针可以指 向它的派生类

,进而实现多态性

c、如果在抽象类的派生类中没有重新说明纯虚函数,则该函数在派生类中

仍然为纯虚函数,而这个派生类仍然还是一个抽象类。

注:在实现动态多态时,一般将基类的析构函数声明为虚函数,不然如:当声明一个

指向基类的引用,然后用这个引用指向派生类,析构时,只调用基类的析构函数

,而不会调用派生类的。如果将基类的析构函数声明为虚函数,那么就会先调用派

生类的析构函数,再调用基类的构造函数。而且其所有层次的派生类的析构函数

都自动成为了虚析构函数。

五、接口

:仅有纯虚函数,且没有数据成员的类

如果一个类继承某个接口类,则说明该类支持这个接口。当然该类也应该实现这个接口

的全部成纯虚函数。

注:在声明一个接口类时,经常用struct,而不是class,因为sturct的默认访问机制

是pulbic,而class的是private

六、虚函数与动态绑定

动态绑定:虚函数的调用机制

C++编译器通过虚函数表(v-table)和虚函数表指针(vptr)来实现。

如果一个类定义了虚函数,则编译器就会为该类创建一个虚函数表。虚函数表

是一个数组,其中的每一个元素都是函数指针,指向该类的虚函数。

编译器会为该类的对象嵌入一个虚函数表指针,从而建立对象和虚函数表的索引

关系,编译器也会派生类创建虚函数表,如果派生类没有改写基类中的虚函数,则

其虚函数表的内容只是基类虚函数表的复制。如果派生类改写了基类中的虚函数,

则其虚函数表中的元素就是改写后虚函数的地址。

编译时的动态绑定过程:

1、编译器通过对象地址计算得到虚函数表指针(vptr)

2、通过虚函数表指针得到虚函数表(v-table)的地址

3、根据被调虚函数在类中的次序,得到该虚函数的地址在虚函数表中的索引

4、根据这个索引获取虚函数的入口地址,也就是实际所调虚函数的地址。

七、虚函数的默认实参

1、如果是一个基类类型的指针或引用,则使用基类中的默认实参

2、如果是派生类类型的指针或引用,则使用派生类中的默认实参。

八、虚函数的静态调用

调用基类中的虚函数,而不是派生类中重写的虚函数

语法:

派生类对象指针->基类名::虚函数名();


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值