欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

虚基类小思

程序员文章站 2022-06-08 18:16:37
...

虚基类的形式

虚基类就是在继承基类时,在继承类别(public、protect、private等)前加限定词virtual,形如:

class base{}//基类
class base_virtual:virtual public base{}//这就是虚基类的形式

虚基类存在的意义

在基类继承关系比较复杂的时候,基类成员的继承关系会引起混乱,例如:
虚基类小思
此时,子类grandchild想继承parent中的int a ,但是该如何继承呢?具体通过child1还是child2,这个途径是不清楚的,因此定义了虚基类,使得他们的继承关系变得明确。

虚基类的具体继承方式

说明的代码如下:

#include<iostream>
using namespace std;
	class par{
		int n;
	public:
		par(){
			a=2;cout<<"parent="<<a<<endl;}

	protected:
	 int a;
};

class child1:virtual public par{
	int n1;
	public:
		child1(){a+=5;cout<<"child1="<<a<<endl;}
};

class child2:virtual public par{
	int n2;
	public:
	 child2(){a+=8;cout<<"child2="<<a<<endl;}
};
class grandchild:public child1,public child2{
	public:
		grandchild(){cout<<"grandchild a ="<<a<<endl; }
};
int main(){
grandchild example;
return 0;
}

这里grandchild类在child1、child2类上继承,间接继承了par类,它继承的成员变量有n,n1,n2,并且只继承了一次,为了表征这种关系,特意在构造函数内建立了变量a。

  1. 在定义了grandchild类后,系统开始调用grandchild()构造函数,发现他的父类是child1、child2,便先跳转(按继承的顺序)到child1,因为child1在par类上继承,因此再跳到par类进行函数构造,因此,首先有:
	parent=2
  1. par类构造结束,转到child1类进行构造,a继承自par,因此a=2+5=7,所以此时child1的构造函数中会输出:
	child1=7
  1. 如果child1、child2不是虚函数,那么在运行child2的构造函数时,会返回它的继承父类par,重新构造一次,但现在我们有了virtual关键字,就不会这样重新构造,而是继续继承child1之后计算得到的a=7,因此,child2的构造函数会输出:
	child2=15
  1. 在构造完grandchild继承的child1、child2之后,开始运行grandchild自身的构造函数,此时继承child2中的a=15,因此它的构造函数会输出:
	grandchild a =15

(析构的话,方向相反。)
因此,总的程序输出结果为:

	parent=2
	child1=7
	child2=15
	grandchild a =15
	//此处空行是因为grandchild构造函数中的endl...

总结

虚基类是解决类继承关系出现矛盾时一种高效的调整方法。