C++多重继承及多态性
2021-05-01 22:27
标签:抽象 4行 sig 工作 函数 void 依次 类成员 允许 举例: 类名限定 如果存在两个或多个包含关系的作用域,外层声明了一个名字,而内层没有再次声明相同的名字,则外层名字在内层可见;如果在内层声明了相同的名字,则外层名字在内层不可见——隐藏(屏蔽)规则。 在类的派生层次结构中,基类的成员和派生类新增的成员都具有类作用域,二者的作用域不同:基类在外层,派生类在内层。如果派生类声明了一个和基类成员同名的新成员,则派生类的新成员就会屏蔽基类的同名成员,直接使用成员名只能访问到派生类新增的成员。(如需使用从基类继承的成员,应当使用基类名限定) 虚基类的使用目的:在继承间接基类时只保留一份成员。 声明虚基类需要在派生类定义时,指定继承方式的时候声明,只需要在访问标号(public、protected、private继承方式)前加上virtual关键字。注意:为了保证虚基类在派生类中只继承依次,应当在该基类的所有直接派生类中声明为虚基类,否则仍会出现多次继承。 派生类不仅要负责对直接基类进行初始化,还要负责对虚基类初始化;若多重继承中没有虚基类,则派生类只需要对间接基类进行初始化,而对基类的初始化由各个间接基类完成(会因此产生多个基类的副本保存在各个间接基类中)。 关于虚基类的说明: 虚函数只能是类中的成员函数,且不能是静态的; virtual关键字只能在类体中使用,即便虚函数的实现在类体外定义,也不能带上virtual关键字; 当在派生类中定义了一个与基类虚函数同名的成员函数时,只要该函数的参数个数、类型、顺序以及返回类型与基类中的完全一致,则派生类的这个成员函数无论是否使用virtual关键字,它都将自动成为虚函数; 利用虚函数,可以在基类和派生类中使用相同的函数名定义函数的不同实现,达到「一个接口,多种方式」的目的。当基类指针或引用对虚函数进行访问时,系统将根据运行时指针(或引用)所指向(或引用)的实际对象来确定调用的虚函数版本; 使用虚函数并不一定产生多态性,也不一定使用动态联编。如:在调用中对虚函数使用类名限定,可以强制C++对该函数使用静态联编。 在派生类中,当一个指向基类成员函数的指针指向一个虚函数,并且通过指向对象的基类指针(或引用)访问这个虚函数时,仍将发生多态性。 使用虚函数,系统要增加一定的空间开销存储虚函数表,但是系统在进行动态联编时的时间开销时很少的,因此,虚函数实现的多态性是高效的。 派生类的对象从内存中撤销时一般先调用派生类的析构函数,然后再调用基类的析构函数。但如果用new运算符建立了派生类对象,且定义了一个基类的指针指向这个对象,那么当用delete运算符撤销对象时,系统会只执行基类的析构函数,而不执行派生类的析构函数,因而也无法对派生类对象进行真正的撤销清理工作。 如果希望delete关键字作用于基类指针时,也执行派生类的析构函数,则需要将基类的析构函数声明为虚函数。 如果将基类的析构函数声明为虚函数,则由该基类所派生的所有派生类的析构函数也都自动成为虚函数,即使派生类的析构函数与基类的析构函数名字不相同。 C++支持虚析构函数,但是不支持虚构造函数,即构造函数不能声明为虚函数! 许多情况下,不能在基类中为虚函数给出一个有意义的定义,这时可以将它说明为纯虚函数,将具体定义留给派生类去做。纯虚函数的定义形式为: 包含有纯虚函数的类称为抽象类,一个抽象类只能作为基类来派生新类,因此又称为抽象基类,抽象类不能定义对象(实体)。 重载多态——函数重载、运算符重载 强制多态——也称类型转换 C++的基本数据类型之间转换规则: 可以在表达式中使用3中强制类型转换表达式: 类型参数化多态——模板(函数模板、类模板) 包含多态——使用虚函数 至少含有一个虚函数的类称为多态类,虚函数使得程序能够以动态联编的方式达到执行结果的多态化。这种多态使用的背景是:派生类继承基类的所有操作,或者说,基类的操作能被用于操作派生类的对象,当基类的操作不能适应派生类时,派生类就需要重载基类的操作;其表现为C++允许用基类的指针接收派生类的地址或使用基类的引用绑定派生类的对象。 联编:将模块或者函数合并在一起生成可执行代码的处理过程,同时对每个模块或者函数分配内存地址,并且对外部访问也分配正确的内存地址。 静态联编:在编译阶段就将函数实现和函数调用绑定。静态联编在编译阶段就必须了解所有函数的或模块执行所需要的信息,它对函数的选择是基于指向对象的指针(或者引用)的类型。C语言中,所有的联编都是静态联编,C++中一般情况下的联编也是静态联编。 动态联编:在程序运行的时候才进行函数实现和函数调用的绑定称之为动态联编(dynamic binding) 当调用虚函数时,先通过vptr指针(编译虚函数时,编译器会为类自动生成一个指向虚函数表的vptr指针)找到虚函数表,然后再找出虚函数的真正地址,再调用它 派生类能继承基类的虚函数表,而且只要是和基类同名(参数也相同)的成员函数,无论是否使用virtual声明,它们都自动成为虚函数。如果派生类没有改写继承基类的虚函数,则函数指针调用基类的虚函数;如果派生类改写了基类的虚函数,编译器将重新为派生类的虚函数建立地址,函数指针会调用改写后的虚函数。 C++多重继承及多态性 标签:抽象 4行 sig 工作 函数 void 依次 类成员 允许 原文地址:https://www.cnblogs.com/coro/p/13205561.html一、多重继承的二义性问题
#include
void hun() { BaseA::fun(); } //改写上述代码的第14行,用BaseA类名限定调用的函数
d.BaseB::fun(); //派生类对象调用基类同名函数时,使用类名限定
p->BaseB::fun(); //派生类指针调用基类同名函数时,使用类名限定
名字支配规则
#include
二、虚基类
#include
三、虚函数
虚函数概念:被virtual关键字修饰的成员函数,即为虚函数,其作用就是实现多态性。
虚函数使用说明:
#include
虚函数实现多态的条件(同时满足)
虚析构函数
纯虚函数
virtual 返回类型 函数名(形式参数列表) = 0;
四、多态性
多态的含义:指同一操作作用于不同的对象时产生不同的结果。
char→short→int→unsigned→long→unsigned→float→double→long double
static_cast
或T(E)
或(T)E
其中E代表运算表达式(获得一个值),T代表一个类型标识符。强制多态使得类型检查复杂化,尤其在允许重载的情况下,会导致无法消解的二义性。静态联编和动态联编
#include
动态联编与虚函数
上一篇:java杂项
下一篇:C语言数据结构-队列Queue