(C/C++学习心得)5.C++中的虚继承-虚函数-多态解析
说明:在C++学习的过程中,虚继承-虚函数经常是初学者容易产生误解的两个概念,它们与C++中多态形成的关系,也是很多初学者经常产生困惑的地方,这篇文章将依次分别对三者进行解析,并讲述其之间的联系与不同。
一.虚继承
1.在多继承中,对于多个父类的数据及函数成员,虽然有时候把他们全部继承下来是有必要的,比如当这些成员都不同的时候。但在大多数的情况下,比如当多个父类之中的成员有重叠的地方时,因为保留多份数据成员的拷贝,不仅占有了较多的存储空间,还增加了访问的难度(由于继承了来自多个父类的同名数据成员,访问时需要加上父类的作用域,比如“父类名::成员”)。
2.在虚继承中,被虚继承的类叫做虚基类,虚基类是需要设计和抽象的,它应当提取多继承父类中重叠的部分作为成员,虚继承是对继承的一种扩展。
示例1:
查看代码
程序运行结果:
1获
在本例中,如果仅仅采用的是多继承而非虚继承,如下代码所示:
查看代码
则sb.dis()就有问题了;因为它产生了二义性,编译器不知道该调用哪一个父类的成员函数,而正确做法是加上父类的作用域,这无疑是增加了访问了难度。
结论:多继承带来的数据存储多份,占用内存空间较多,并且访问不便(作用域的增加)。
二.纯虚函数
1.纯虚函数的格式:
复制代码
1 class A
2 {
3 virtual void func() = 0;
4 }
复制代码
2.含有纯虚函数的类为抽象基类,不可创建对象,其存在的意义就是被继承,提供族类的公共接口,
3.纯虚函数只有声明,没有实现,被初始化为0,
4.如果一个类中声明了纯虚函数,而在派生类中没有对该函数定义,则该函数在派生类中仍然为纯虚函数,派生类仍然为纯虚基类,
5.含有虚函数的类,析构函数也应该声明为虚函数,这样在delete父类指针的时候,才会调用子类的析构函数,实现完整析构,
查看代码
程序运行结果:
2获
注意:若在此例中,没有将含有虚函数的父类析构函数声明为虚函数,则将不会调用子类的析构函数~B()实现完整析构。
三.多态的实现
1.C++中的多态指的是由于继承而产生的相关的不同的类,其对象对同一消息会做出不同的反应。
2.多态实现的前提是赋值兼容,赋值兼容的内容如下:
a.子类的对象可以赋值给基类的对象,
b.子类的对象可以赋值给基类的引用,
c.子类对象的地址可以赋值给基类的指针(一般用于动多态的实现),
d.在赋值后,子类对象就可以作为基类对象使用,但只能访问从基类继承的成员.
3.动多态的实现条件:
a.父类中有虚函数,
b.子类override(覆写)父类中的虚函数,
c.将子类的对象赋值给父类的指针或引用,由其调用公用接口.
查看代码
注意:C++中的多态一般指动多态,其实C++中函数的重载也是一种多态现象,其通过命名倾轧在编译阶段决定,故称为静多态;而动多态一般是在父子类中在运行阶段决定的。https://www.cnblogs.com/tuihou/p/9718335.html