C++继承-补充

本期对继承的知识进行一些补充,还没看过之前对继承讲解的建议先看之前的

C++继承_KLZUQ的博客-CSDN博客

本期补充知识为菱形继承以及菱形虚拟继承相关知识

class A 
{
public:
	virtual void func1()
	{
		cout << "A::func1" << endl;
	}
public:
	int _a; 
};
class B : public A
//class B : virtual public A
{
public:
	int _b;
};
class C : public A
//class C : virtual public A
{
public:
	int _c;
};
class D : public B, public C
{
public:
	int _d;
};

 C++继承-补充_第1张图片

我们进入调试,然后看内存窗口,&d,一上来就可以看到两个指针 ,这里就是虚表的指针

C++继承-补充_第2张图片

当我们走完时,可以看到里面1,2,3,4,5的变化 

也就是说,我们单纯的看菱形继承,其实是和多继承没有区别的

C++继承-补充_第3张图片

 下面我们再看看菱形虚拟继承

C++继承-补充_第4张图片

菱形虚拟继承又分为几个问题,首先是只有A里面有虚函数 ,此时是将A单独拿出来了,放在了下面,这里我们说过了

C++继承-补充_第5张图片

 而它不同的地方在于,我们上面给A写了func1函数,如果我们对他进行重写

C++继承-补充_第6张图片

我们会发现,首先编译会报错 ,不重写还没事,B和C重写后就有问题了,这是为什么?

原因是,这里A是属于B和C共享的,B去重写,C也去重写,那到底是谁去重写?

C++继承-补充_第7张图片

我们先把重写的func去掉,然后此时只有A里面有func1, 只有一张虚表,只有A有虚函数,B也要重写,C也要重写,就不行了

C++继承-补充_第8张图片

解决方案是让D也去重写 ,此时B,C,D都进行了重写

此时就会有人问,那B和C为什么还要去重写?直接让D重写不就好了吗?其实我们在实际中不仅仅会定义D对象,B和C对象也是可能定义的

对于菱形继承,D里面的B和C各自有各自的A,所以重写没有问题,但是菱形虚拟继承,这个A变成公共的了,B也要用,C也要用,那就都别用了,让D用吧

菱形虚拟继承还有更复杂的问题

C++继承-补充_第9张图片

B和C增加一些新的虚函数,这些虚函数不是重写A的,那该怎么办?

C++继承-补充_第10张图片

此时B和C就会各自再建一张虚表 

C++继承-补充_第11张图片

画出来就是这样,如果我们再开几个内存窗口验证的话,比如我们验证B,我们看地址00329d4c和00329d60,就可以发现一个是虚表,存的虚函数地址,另一个是虚机表,存的偏移量

C++继承-补充_第12张图片

我们再给D单独加一个func3,大家猜一猜会不会再建立一个虚表?

C++继承-补充_第13张图片

答案是不会,它直接放在A的虚表里了

以上即为本期全部内容,希望大家可以有所收获

如果错误,还请指正 

你可能感兴趣的:(c++,算法,数据结构,继承)