1.菱形的相关问题
1.什么是菱形继承?
菱形继承是C++继承中的多继承出现的问题。
2.菱形继承带来什么问题,如何解决?
带来数据二义性,和数据冗余问题。
二义性可以通过作用域限定符,限定所操作的数据对象。
数据冗余问题,需要通过虚拟继承来解决。
图解:
3.什么是组合,什么是继承,适用情况有哪些?
组合和继承都是面向对象编程代码复用的方式。
组合是解决has-a的问题,(车有发动机)。
优点:封装性没有被破坏,类与类的耦合度低。
缺点:调用的时候是通过对象访问调用接口,不能直接使用接口。
继承是解决Is-a的问题,(人,学生,老师)
优点:子类直接继承父类的接口,创建对象时不用创建父类对象。
缺点:父类与子类的耦合度增加,破坏了封装性,不利于程序的维护。
2.代码展示
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class per
{
public:
int _num1;
};
class stu:virtual public per
{
public:
int _num2;
};
class teach :virtual public per
{
public:
int _num3;
};
class ass : public teach, public stu
{
public:
int _num4;
};
void test6()
{
per p;
p._num1 = 1;
cout << p._num1 << endl;
stu s;
s._num1 = 21, s._num2 = 22;
cout << s._num1 <<" "<< s._num2 << endl;
teach t;
t._num1 = 31, t._num3 = 33;
cout << t._num1 << " " << t._num3 << endl;
ass a;
a._num1 = 41, a._num2 = 42, a._num3 = 43, a._num4 = 44;
a.stu::_num1 = 411, a.teach::_num1 = 4111;
cout <<a._num1 << " " << a._num2 << " " << a._num3 << " " << a._num4 << endl;
cout << t._num1 << " " << t._num3 << endl;
//printf("%p", *(int*)&a);
}
int main()
{
test6();
system("pause");
return 0;
}
3.结果展示
4.结果分析
通过查看地址的方式,我发现虚拟继承virtual继承,子类继承父类的时候,增加了一个虚基表指针,指向虚基表,虚基表的位置存储的是00000000,下一个位置存储的是偏移量,即虚基表指针到数据的位置,结尾一般是00000000,而且它们共用一个虚基表。重复的冗余的数据,放在数据的末尾。
虚基表在内存中放在数据段,下面通过查看地址发现两个位置非常近。