多态

多态

一、重写/覆盖 

虚函数:可以被重写的函数,virtual修饰

当派生类继承基类后,如果基类中含有虚函数,子类可以对虚函数执行重写(覆盖),方法是写一个跟它完全相同的函数(函数名、参数列表、返回值都相同),就会覆盖掉原来的函数。

覆盖后,无论用基类指针还是派生类指针,都会调用覆盖后的函数。

特例:

协变:假如B继承自A,D继承自C,那么A中虚函数返回了C类指针,B中虚函数返回了D类指针,这种情况也构成重写。

二、虚析构函数:

所有析构函数在底层的函数名都是相同的

***虚析构函数是用来解决子类对象转化为父类对象进行析构的问题的。(子父析构函数覆盖掉父析构函数)

三、final & override

C++11

final:不能被继承的类或者不能被重写的虚函数(写在父类)

override:声明子类的某个函数必须重写父类的某个虚函数(子类)

四、重载/重写/隐藏

重载:针对函数,重名,参数列表不同

重写/覆盖:针对继承,完全相同(协变例外),只在虚函数/纯虚函数中存在

隐藏/重定义:针对继承,重名,不能是虚函数

***重写是换了一个函数,隐藏是藏一个函数,所以重写是一个函数,隐藏是两个函数

五、抽象类:

纯虚函数:只有接口,没有实现的函数。

包含纯虚函数的类叫做抽象类,抽象类不能定义对象。

六、虚表:32位4字节 64位8字节

虚表是一个二级函数指针,只要类中包含虚函数,就会在对象的头部包含一个虚表指针(vfptr)

虚表相当于一个函数指针数组,里面存放的就是虚函数的地址。

当子类继承父类时,会继承虚表,当子类有新的虚函数时,会在虚表后面新增新的项,当子类重写父类的虚函数时,会把虚表中原有的某一项覆盖。

七、多重继承

一个派生类可以来源于多个基类,多个基类间用逗号隔开。

如果多个父类中有重名的成员,那么会产生二义,必须用父类名::的方式指明用谁的成员。

如果继承的多个父类中有多个虚表,那么子类将全部继承下来。如果子类出现了新的虚函数,那么会加在第一个虚表(第一个继承的父类的虚表)的后面,如果多个父类中含有相同的虚函数,子类重写后,将会只出现一个虚函数。

八、菱形继承、虚继承(一般,虚继承只用在菱形继承)

菱形继承:某个类的两个父类有一个相同的父类。

BC继承A,C继承BC.(istream,ostream继承ios,iostream继承istream和ostream)

冗余性:这个类包含了两份爷爷类

二义性:两个爷爷长得一样,分不清

虚继承:

含有一个虚基类指针(vbptr)指向自己的基类,作用是可以描述自己的父类。当发现被继承的另一个父类中也有这么一个相同的虚基类时,两个基类就会合并,就只保留一个。

普通的继承只继承了爷爷的衣钵,不知道爷爷是谁。虚继承都知道,所以,发现我的两个爸爸的爸爸是同一个人的时候,干脆就只要一个爷爷。

虚继承可以解决菱形继承带来的冗余性和二义性。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章