【C++】虚函数与多态

上一篇我们留了多继承与虚函数,这次来讲讲,与多态一起协同

多继承就是一个子类继承了多个父类,也就是从原来的

class C(子类) :public A(父类)

变成了--->

class C(子类) :public A(父类) , public B(父类)

以及菱形继承,菱形继承需要用到虚继承解决本身数据冗余的问题,意识是把多个父类通过虚继承减少所消耗的空间。不过一般不推荐使用菱形继承,感兴趣的小伙伴可以找找相关资料。

虚函数是指:被virtual修饰的成员函数,一般父类中拥有一个成员函数 func() ,子类继承了父类的 func() 成员函数,但是在函数调用的时候调用的是父类的函数,为什么呢,因为该成员函数继承了父类的成员函数,没有发生改变,所以调用的仍然是继承下来的父类的成员函数。

【C++】虚函数与多态_第1张图片

 想要改变,就得加上virtual来修饰,即把成员函数转换为虚函数,而虚函数可以抽象地认为与函数重载的效果类似,它的名字叫做虚函数重写,虚函数重写是指:子类中有一个跟父类完全相同的虚函数(即父子类的返回值类 型、函数名字、参数列表完全相同),称子类的虚函数重写了父类的虚函数。

通俗易懂地说,就是表面上函数没有发生变化,其实内部已经改变成子类的了。

【C++】虚函数与多态_第2张图片

 为什么会这样呢,其实每个类中虚函数都会放在一个叫做虚表的空间内,虚表是一个指针,指向了一个逻辑上的表格,表格的内部分别指向类中的虚函数,当然,非虚函数的成员函数不在虚表中。

那么它们在虚表中又是如何分配的,假设两个子类B,C继承了父类A

【C++】虚函数与多态_第3张图片

那虚表是在栈,堆,静态区,还是代码段中呢?我们可以在各个区内取一个变量,比如malloc一个空间,一串字符串,一个全局变量,一个局部变量,再分别打印出地址,哪个里虚表的地址近,哪个就99%是虚表的存放区,1%是万一。-----存在代码段中。

重点:虚函数重写有两种意外,一种是协变,一种是析构函数

协变:返回值的类型不同,是子类和父类的引用或者指针形式返回。

【C++】虚函数与多态_第4张图片

析构函数:析构函数比较特殊,是编译器把析构统一更改名字为destructor,从而达到重写的效果。

下面简单讲一下多态:

多态就是指,多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。它分为静态多态和动态多态:

静态多态就是函数重载,比如:int (a, b)  和 double (a, b) 。

动态多态就是通过父子关系去调用函数,父类指针或引用指向父类(子类)对象,调用父类(子类)的虚函数。

 本节完。

你可能感兴趣的:(C++,c++)