C++虚继承简单讲解

多继承及潜在问题

对象的继承,指的是一个子类对象获得父类对象的所有属性和方法,并且可以在此基础上拓展新的属性和方法的一种行为(个人理解,请勿当真。。)

那么继承可以一直进行,比如c继承自b,b又继承自a,那么c的父类是b,b的父类是a,c的爷类是a,这好理解

但是值得注意的是,c++可以支持多继承
这意味着

  1. 一个类可以有多个爹(父类)
  2. 爹类(父类)们,可能拥有共同的父类
  3. 那么一个类可能会拥有多个爷类,这时候就会发生冲突,因为爷类是同一个(即如下图的a)

在这里插入图片描述
这个时候就会发生问题,因为继承的特性是:子类先创建父类的对象,在创建子类自己的属性,那么会创建两个爷类对象,可是实际生产生活中一般只用一个爷类对象就够了,这可能有些抽象,所以举个例子:

  1. 有一个animal动物类,animal类有age年龄属性
  2. cat类和dog类继承自animal类
  3. 出现了新物种:catdog,catdog类继承自cat类和dog类(多继承)

按照继承特性,继承自cat和dog,cat和dog都会创建一个animal对象,所以catdog类有两个animal对象,那么catdog拥有两个年龄属性

可是客观描述和实际编程,年龄都是唯一的变量,这就造成了冲突和客观描述上的矛盾,而且造成了不必要的内存开销

更致命的是,同名的age变量更容易造成冲突与bug

如下的代码揭示了这种不合理的情况(即创建两个animal对象)
在这里插入图片描述

#include <bits/stdc++.h>

using namespace std;

class animal
{
public:
	int age;
	animal(){cout<<"animal对象被创建"<<endl;}
};

class cat : public animal
{
public:
	int c;
	cat(){cout<<"cat对象被创建"<<endl;}	
};

class dog : public animal
{
public:
	int d;
	dog(){cout<<"dog对象被创建"<<endl;}	
};

class catdog : public cat, public dog
{
public:
	int cd;
	catdog(){cout<<"catdog对象被创建"<<endl;}
};

int main()
{ 	
	catdog cd;
	
	return 0;
}

解决方案:虚继承

因为继承的特性,子类在创建的时候,会先创建父类,所以上述问题会有两个爷类的情况出现,而我们需要消灭一个爷

虚拟继承的解决方法,是使得多继承的时候,某个公共基类的成员在其派生类(子类)中只产生一个拷贝

实现方法:virtual关键字

cat类和dog类在继承基类animal的时候,加上virtual关键字,就会使得在后续的多继承中,如果catdog类的父类cat和dog都继承自animal,那么只会产生一个animal对象而不是两个

在这里插入图片描述

代码

#include <bits/stdc++.h>

using namespace std;

class animal
{
public:
	int age;
	animal(){cout<<"animal对象被创建"<<endl;}
};

// 继承基类时加上 virtual 关键字
class cat : virtual public animal
{
public:
	int c;
	cat(){cout<<"cat对象被创建"<<endl;}	
};

// 继承基类时加上 virtual 关键字
class dog : virtual public animal
{
public:
	int d;
	dog(){cout<<"dog对象被创建"<<endl;}	
};

class catdog : public cat, public dog
{
public:
	int cd;
	catdog(){cout<<"catdog对象被创建"<<endl;}
};

int main()
{ 	
	catdog cd;
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章