继承&多态

来源:互联网 发布:星际战甲软件 编辑:程序博客网 时间:2024/05/27 12:21

单继承&多重继承

单继承:一个子类只有一个直接父类

多重继承:一个子类有两个或以上直接父类



#include <iostream>using namespace std;class Person{public:string _name;};class Student :public Person{public:string _num;};class Teacher :public Person{public:string _id;};class Assistant :public Student, public Teacher{public:string _majorCourse;};int main(){Assistant a;a.Student::_name = "xxx";a.Teacher::_name = "yyy";}



虚继承-解决菱形继承的二义性和数据冗余的问题

1.虚继承解决了在菱形继承体系里面子类包含多份父类对象的数据冗余&浪费空间的问题

2.虚继承体系看起来好复杂,在实际应用中我们不会定义如此复杂的继承体系,一般不到万不得已一定不要定义菱形结构的虚继承体   系结构,因为使用虚继承解决数据冗余的问题也带来了性能上的损耗。


虚继承&多态

虚继承:类的成员函数前面加virtual关键字,则这个成员函数称为虚函数

虚函数重写:当在子类的定义了一个与父类完全相同的虚函数时,则称子类的这个函数重写(也称覆盖)了这个父类                       的虚函数

#include <iostream>using namespace std;class Person{public:virtual void BuyTickeys(){cout << "全票" << endl;}};class Student:public Person{public:virtual void BuyTickeys(){cout << "半件" << endl;}};void Func(Person &p){p.BuyTickeys();}int main(){Person p;Student s;Func(p);Func(s);}
运行结果:


class A{public:int  _a;};class B : virtual public A{public:int _b;};class C :virtual public A{public:int _c;};class D :public B, public C{public:int _d;};int main(){D d;d._a = 10;}

采用虚继承和显示指定访问父类成员,对对象所产生的的影响有什么不同呢?显示指定访问并不能起到一改全改的作用,那么就会造成一个对象d有两个不相同的成员_a,明显是不符合常规的。




显然我们不用显示的指定访问哪个父类的成员,但是可以清晰看到d的大小并不是期望中的16,而是24个字节,这是为什么呢?


现在来了解多出来的四个字节究竟是什么?首先我们通过调试——>内存查看对象d的地址的数据,可以看到如下现象:



(1)(2)中存放的数据究竟是用来表示什么的呢?再将d._a分别赋值成为0和4,通过内存窗口观察d的地址的数据

由图可以看到末排的地址存放的数据刚好是d._a的值的大小,那么多出来的第一排和第三排的数据看起来似乎是两个地址,输入地址查看一下数据



由图可以看到末排的地址存放的数据刚好是d._a的值的大小,那么多出来的第一排和第三排的数据看起来似乎是两个地址,输入地址查看一下数据



明显可以看到两个地址存放的数据是每个对象相对于基类的成员的偏移量,对应的每个地址所代表的意义如下:



这样也就可以解释为什么d的大小为24个字节因为虚继承引入了间接性指针

6.在虚继承的前提下,重新建立对象模型





原创粉丝点击