虚继承的作用:防止产生二义性
先来看一看下面的一段代码吧:
#define _CRT_SECURE_NO_WARINGS
#include<iostream>
#include<string>
using namespace std;
class Grandfather
{
public:
Grandfather() { cout << "爷爷的构造函数" << endl; }
~Grandfather() { cout << "爷爷的析构函数" << endl; }
};
class Father :public Grandfather
{
public:
Father() { cout << "爸爸的构造函数" << endl; }
~Father() { cout << "爸爸的析构函数"<<endl; }
};
class Mother :public Grandfather
{
public:
Mother() { cout << "妈妈的构造函数" << endl; }
~Mother() { cout << "妈妈的析构函数" << endl; }
};
class Children :public Father, public Mother
{
public:
Children() { cout << "儿子的构造函数" << endl; }
~Children() { cout << "儿子的析构函数" << endl; }
};
int main()
{
Children me;
return 0;
}
下面我们再来看一看他的输出结果:
现在我们对运行结果进行分析不难得出:执行Children时必须先执行Father类(因为Children公有继承了Father)但是往前面找到Father类我们又发现它公有继承了Grandfather类,因此最先执行的是Grandfather的构造函数,再执行Father和Mother的构造函数,最后执行自己的构造函数。析构函数的话与构造函数的顺序相反。
在这条代码的输出结果中我们发现,Children继承了两次爷爷类,这无疑会增加程序的运行时间,如果我们只想继承一次爷爷类就要使用到虚继承的知识。虚继承可以使子类只继承一次父类的父类。实现方法很简单:就是在Father和Mother继承爷爷类之前加一个virtual即可
代码:
#define _CRT_SECURE_NO_WARINGS
#include<iostream>
#include<string>
using namespace std;
class Grandfather
{
public:
Grandfather() { cout << "爷爷的构造函数" << endl; }
~Grandfather() { cout << "爷爷的析构函数" << endl; }
};
class Father :virtual public Grandfather
{
public:
Father() { cout << "爸爸的构造函数" << endl; }
~Father() { cout << "爸爸的析构函数"<<endl; }
};
class Mother :virtual public Grandfather
{
public:
Mother() { cout << "妈妈的构造函数" << endl; }
~Mother() { cout << "妈妈的析构函数" << endl; }
};
class Children :public Father, public Mother
{
public:
Children() { cout << "儿子的构造函数" << endl; }
~Children() { cout << "儿子的析构函数" << endl; }
};
int main()
{
Children me;
return 0;
}
运行结果:
为什么析构函数必须是虚函数
首先我们先来复习一下
多态的三要素:
一、要有子类继承父类
二、要有虚函数
三、父类指针指向对象
来看看这个代码:
#include<iostream>
using namespace std;
class Father
{
public:
~Father() { cout << "父类的析构函数" << endl; }
};
class Son :public Father
{
public:
~Son() { cout << "子类析构函数"; }
};
int main()
{
Father* p = new Son;
delete p;
return 0;
}
他的运行结果:
从运行结果我们可以发现:子类的析构函数没有被调用,子类的资源内存没有被释放,这会造成内存泄漏,解决方法很简单,我们把Father类的析构函数写成虚函数即可
#include<iostream>
using namespace std;
class Father
{
public:
virtual ~Father() { cout << "父类的析构函数" << endl; }
};
class Son :public Father
{
public:
~Son() { cout << "子类析构函数"<<endl; }
};
int main()
{
Father* p = new Son;
delete p;
return 0;
}
模板类的继承(继承子类的所有属性)
继承的遗传性(继承基类的所有属性)
#include<iostream>
using namespace std;
class A
{
public:
A(int a):a(a){}
int a;
};
class B:public A
{
public:
//B需要调用A的构造函数A()
B(int a,int b):b(b),A(a){}
//int a; 有a的属性
int b;
};
class C :public B
{
public:
//C需要调用B的构造函数但是不需要调用A的构造函数
C(int a,int b,int c):c(c),B(a,b){}
//int a ,b;有a b 的属性
int c;
};
class D :public C
{
public:
//D只需要调用C的构造函数
D(int a,int b,int c,int d):d(d),C(a,b,c){}
//int a,b,c;有a b c的属性
int d;
void print()
{
cout << "a= " << a << " b= " << b << " c= " << c << " d= " << d << endl;
}
};
int main()
{
cout << "I Love You" << endl;
D object(1, 2, 3, 4);
object.print();
return 0;
}
输出:
I Love You
a= 1 b= 2 c= 3 d= 4
214135