c++学习之继承篇

c++学习之继承篇

编码文章call10242025-04-25 11:10:5414A+A-

虚继承 是面向对象编程中的一种技术,是指一个指定的基类,在继承体系结构中,将其成员数据实例共享给也从这个基类型直接或间接派生的其它类。形式:在继承定义中包含了virtual关键字的继承关系,如下图中,类A就叫做虚基类。

虚拟继承是多重继承中的菱形继承所特有的概念。虚拟基类是为解决多重继承而出现的。

菱形继承中既有多继承,如下图所示:

菱形继承中也有多重继承:

现实中的例子:

问题来了:在类D的实例中将有两份类A的变量,这种数据冗余的现象我们不能容忍其存在?这就会需要用到虚继承!!!废话不多说直接上代码,直接粘贴可用。

#include <iostream>

#include <stdlib.h>

#include <string>

using namespace std;

/**

* 定义人类: Person

*/

class Person

{

public:

Person(string color = "blue"):m_strColor(color)

{

cout << "Person" << endl;

}

~Person()

{

cout << "~Person" << endl;

}

void eat()

{

cout << m_strColor << endl;

// cout << m_iAge << endl;

cout << "Person -- eat" << endl;

}

protected:

string m_strColor;

};

/**

* 定义工人类: Worker

* 虚继承人类

*/

class Worker : virtual public Person

{

public:

Worker(string name,string color):Person("Worker"+color)

{

m_strName = name;

cout << "Worker" << endl;

}

~Worker()

{

cout << "~Worker" << endl;

}

void work()

{

cout << m_strName << endl;

cout << "work" << endl;

}

protected:

string m_strName;

};

/**

* 定义儿童类:Children

* 虚继承人类

*/

class Children : virtual public Person

{

public:

Children(int age,string color):Person("Children"+ color)

{

m_iAge = age;

cout << "Children" << endl;

}

~Children()

{

cout << "~Children" << endl;

}

void play()

{

cout<<

cout << m_iAge << endl;

cout << "play" << endl;

}

protected:

int m_iAge;

};

/**

* 定义童工类:ChildLabourer

* 公有继承工人类和儿童类

*/

class ChildLabourer:public Children,public Worker

{

public:

ChildLabourer(string name, int age,string color):Worker(name,color),Children(age,color)

{

cout << "ChildLabourer" << endl;

}

~ChildLabourer()

{

cout << "~ChildLabourer" << endl;

}

};

int main(void)

{

// 用new关键字实例化童工类对象

ChildLabourer * p = new ChildLabourer("qq",14,"yellow");

// 调用童工类对象各方法。

// p->eat();

p->Worker::eat();

p->Children::eat();

p->work();

p->play();

delete p;

p = NULL;

return 0;

}

输出:

Person

Children

Worker

ChildLabourer

blue

Person -- eat

blue

Person -- eat

qq

work

0x60314814

play

~ChildLabourer

~Worker

~Children

~Person

如果不加virtual关键字时候的输出:

Person

Children

Person

Worker

ChildLabourer

Workeryellow

Person -- eat

Childrenyellow

Person -- eat

qq

work

0x60310814

play

~ChildLabourer

~Worker

~Person

~Children

~Person

分析:

(1)不加virtual情况:

不加virtual,也就是不是虚继承的情况下,在实例化童工这个类的时候,会按继承顺序,先调用类Children的构造函数再调用类Worker的构造函数,最后调用自己的构造函数,而调用Children和Worker的构造函数的时候又会分别先调用它们的基类Person的构造函数,这样就会生成两个Person的对象,从而生成两份Person所含有的数据成员,即童工类ChildLabourer在实例化的时会生成在内存中会生成两份Person的数据成员,所以在调用Children和Worker的eat()函数的时候,会分别打印出Workeryellow和Childrenyellow,(这里注意Children和Worker里面的eat()都是从Person继承来的,因此分别都会打印出Person --eat;还要注意调用方式:p->Worker::eat();p->Children::eat())

销毁对象时,会先调用自己的析构函数,再调用两个基类的析构函数,两个基类的析构函数调用之前都会先调用Person的析构函数。调用析构函数的顺序和调用构造函数相反。

(2)加virtual的情况:

加virtual以后,从输出结果可以看出,在实例化童工类ChildrenLabourer时,构造函数的调用顺序比较正常,只调用了一次Person,析构函数的调用也只会调用一次Person的析构函数,这说明实例化童工类时只会生成一份Person的对象,表明了在对象的内存空间中仅仅能够包含一份虚基类的对象,而且打印的结果都是blue,即ChildrenLabourer的数据不会再传入虚基类Person。这就讲数据冗余的问题解决了。

最后,如果你想学C/C++可以私信小编“01”获取素材资料以及开发工具和听课权限哦!

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4