C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)C++远征之继承篇视频教程笔记方便自己查阅和复习,温故而知新。接着C++继承(1):继承方式(public,protected,private),继承中的特殊关系(隐藏,is-a)继续做笔记目录4多继承与多重继承4.1多重继承4.2多继承代码示例5虚继承代码示例参考资料4多继承与多重继承4.1…

大家好,欢迎来到IT知识分享网。

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

C++远征之继承篇 视频教程 笔记 方便自己查阅和复习,温故而知新。

接着  C++ 继承(1): 继承方式(public, protected, private), 继承中的特殊关系(隐藏 , is-a) 继续做笔记

 

目录

4 多继承与多重继承

4.1  多重继承

4.2  多继承

代码示例

5 虚继承

代码示例

参考资料


 

 

4 多继承与多重继承

4.1  多重继承

如下图示,士兵类 继承 人类 , 步兵类 继承 士兵类。我们称之为 这三者 属于 多重继承关系

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

我们还可以知道 这三者 相互之间 是 is-a 关系

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

在代码中 可以写为:

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

 

 

4.2  多继承

一个类有两个及以上的父类,称之为 多继承。注意区别前面的 多重继承

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

在代码中 形式为:

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

 

代码示例

示例1:多重继承
要求:
1 定义Person类
    数据成员: m_strName 
    成员函数:构造函数  析构函数 play()

2 定义Soldier类:
    数据成员: m_iAge
    成员函数:构造函数  析构函数  worker()

3 定义Infantry类 
    数据成员:无
    成员函数: 构造函数 attack()

4 定义函数test1(Person p) test2(person &p) test3(Person *p)

//Person.h
#pragma once
#include<iostream>
#include<string>
using namespace std;

class Person
{
public:
	Person(string name="pesrson_001");//构造函数
	virtual ~Person();// virtual 防止内存泄漏

	void play();

protected:
	string m_strName;

};
//Person.cpp

#include<iostream>
#include"Person.h"
using namespace std;


Person::Person(string name)
{
	m_strName = name;
	cout << "Person()--构造" << endl;
}

Person::~Person()
{
	cout << "~Person()--析构" << endl;
}

void Person::play()
{
	cout << "Name: " << m_strName << endl;
	cout << "Person--play()" << endl;
}

 

//Soldier.h

#pragma once
#include<iostream>
#include"Person.h"

class Soldier:public Person
{
public:
	Soldier(string name = "soldier_001", int age = 20);
	virtual ~Soldier();//virtual 防止内存泄漏
	void work();

protected:
	int m_iAge;
};
//Soldier.cpp

#include<iostream>
#include"Soldier.h"
using namespace std;
Soldier::Soldier(string name, int age)
{
	m_strName = name;
	m_iAge = age;
	cout << "Soldier()--构造" << endl;
}

Soldier::~Soldier()
{
	cout << "~Soldier()--析构" << endl;
}

void Soldier::work()
{
	cout << "Name= "<< m_strName << endl;
	cout << "Age= " << m_iAge << endl;
	cout << "Soldier--work()" << endl;
}

 

//Infantry.h
#pragma once
#include"Soldier.h"

class Infantry:public Soldier
{
public:
	Infantry(string name = "Infantry_001", int age = 18);
	~Infantry();

	void attack();
};
//Infantry.cpp
#include"Soldier.h"
#include"Infantry.h"
Infantry::Infantry(string name, int age)
{
	m_strName = name;
	m_iAge = age;
	cout << "Infantry()--构造" << endl;
}

Infantry::~Infantry()
{
	cout << "~Infantry()--析构" << endl;
}

void Infantry::attack()
{
	cout << "Name= " << m_strName << endl;
	cout << "Age= " << m_iAge << endl;
	cout << "Infantry--attack()" << endl;
}

 

 

//main.cpp

#include<iostream>
#include"Infantry.h"
using namespace std;
/*************************
多重继承
要求:
1 定义Person类
	数据成员: m_strName 
	成员函数:构造函数  析构函数 play()

2 定义Soldier类:
	数据成员: m_iAge
	成员函数:构造函数  析构函数  worker()

3 定义Infantry类 
	数据成员:无
	成员函数: 构造函数 attack()

4 定义函数test1(Person p) test2(person &p) test3(Person *p)
**************************/
void test1(Person p)
{
	p.play();
}

void test2(Person &p)
{
	p.play();
}

void test3(Person *p)
{
	p->play();
}



int main()
{
	Infantry infantry;
	cout << "---------- 1 -----------" << endl;
	
	test1(infantry); //产生新的临时对象,函数调用后 自动销毁(调用析构函数)

	cout << "" << endl;
	cout << "---------- 2 -----------" << endl;
	cout << "" << endl;

	test2(infantry);

	cout << "" << endl; //没有产生新的临时对象
	cout << "---------- 3 -----------" << endl;
	cout << "" << endl;

	test3(&infantry); //没有产生新的临时对象


	cin.get();
	return 0;
}

运行结果:

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

 

示例2: 多继承

要求:多继承
1 定义Farmer类
    数据成员: m_strName 
    成员函数:构造函数  析构函数 sow()

2 定义Worker类:
    数据成员: m_strCode
    成员函数:构造函数  析构函数  carry()

3 定义MigrantWorker类 
    数据成员:无
    成员函数: 构造函数 析构函数

//Worker.h

#pragma once
#include<iostream>
#include <string>
using namespace std;
class Worker
{
public:
	Worker(string code="Worker_001");
	virtual ~Worker();

	void carry();

protected:
	string m_strCode;
};
//Worker.cpp

#include<iostream>
#include"Worker.h"
using namespace std;

Worker::Worker(string code)
{
	m_strCode = code;
	cout << "Worker()--构造" << endl;
}

Worker::~Worker()
{
	cout << "~Worker()--析构" << endl;
}

void Worker::carry()
{
	cout << "Code= " << m_strCode << endl;
	cout << "Worker--carry()" << endl;
}

 

//Farmer.h

#pragma once
#include<iostream>
#include <string>
using namespace std;
class Farmer
{
public:
	Farmer(string name = "Farmer_001");
	virtual ~Farmer();

	void sow();

protected:
	string m_strName;
};
//Farmer.cpp
#include"Farmer.h"
using namespace std;

Farmer::Farmer(string name)
{
	m_strName = name;
	cout << "Farmer()--构造" << endl;
}

Farmer::~Farmer()
{
	cout << "~Farmer()--析构" << endl;
}

void Farmer::sow()
{
	cout << "Name= " << m_strName << endl;
	cout << "Farmer()--sow()" << endl;
}

 

//MigrantWorker.h
#pragma once
#include<iostream>
#include <string>
using namespace std;

#include"Worker.h"
#include"Farmer.h"

class MigrantWorker:public Worker, public Farmer //继承两个类
{
public:
	MigrantWorker(string name, string code);
	~MigrantWorker();
};
//MigrantWorker.cpp

#include"MigrantWorker.h"
using namespace std;
MigrantWorker::MigrantWorker(string name, string code):Farmer(name),Worker(code)
{
	cout << "MigrantWorker()--构造" << endl;
}


MigrantWorker::~MigrantWorker()
{
	cout << "~MigrantWorker()--析构" << endl;
}

 

//main.cpp

#include<iostream>
#include"MigrantWorker.h"
using namespace std;
/*************************
多继承
要求:
1 定义Farmer类
	数据成员: m_strName 
	成员函数:构造函数  析构函数 sow()

2 定义Worker类:
	数据成员: m_strCode
	成员函数:构造函数  析构函数  carry()

3 定义MigrantWorker类 
	数据成员:无
	成员函数: 构造函数 析构函数
**************************/

int main()
{
	MigrantWorker *p = new MigrantWorker("HAHA","002");
	cout << "---------- 1 -----------" << endl;
	cout << "" << endl;

	p->carry();
	p->sow();
	cout << "---------- 2 -----------" << endl;
	cout << "" << endl;

	delete p;
	p = NULL;


	cin.get();
	return 0;
}

 

运行结果:

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

 

 

 

5 虚继承

 

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

上面的这种继承属于菱形继承如果实例化对象D 那么D—>B—>A  D—>C—>A , 此时D将会从A得到两个相同的数据,这属于数据冗余,是不能容忍的。

 

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

那么菱形继承 需要用 虚继承 来解决数据冗余的问题,格式如下图所示:

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

 

 

代码示例

要求:虚继承  比较 使用虚继承和 不使用虚继承 之间的区别
1 定义Farmer类
    数据成员: m_strName
    成员函数:构造函数  析构函数 sow()

2 定义Worker类:
    数据成员: m_strCode
    成员函数:构造函数  析构函数  carry()

3 定义MigrantWorker类
    数据成员:无
    成员函数: 构造函数 析构函数

4 Person 
    数据成员: m_strColor
    成员函数:构造函数  析构函数 printColor()

 

//Person.h
#pragma once
#include<iostream>
#include<string>
using namespace std;

class Person
{
public:
	Person(string clolr = "blue");//构造函数
	virtual ~Person();// virtual 防止内存泄漏

	void printColor();

protected:
	string m_strColor;

};
//Person.cpp

#include<iostream>
#include"Person.h"
using namespace std;


Person::Person(string color)
{
	m_strColor = color;
	cout << "Person()--构造" << endl;
}

Person::~Person()
{
	cout << "~Person()--析构" << endl;
}

void Person::printColor()
{
	cout << "Color: " << m_strColor << endl;
	cout << "Person--printColor()" << endl;
}

 

//Farmer.h

#pragma once
#include<iostream>
#include <string>
#include"Person.h"
using namespace std;
class Farmer :public Person
{
public:
	Farmer(string name = "Farmer_001", string color = "blue");
	virtual ~Farmer();

	void sow();

protected:
	string m_strName;
};

//Farmer.cpp
#include"Farmer.h"
using namespace std;

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

{
	m_strName = name;
	cout << "Farmer()--构造" << endl;
}

Farmer::~Farmer()
{
	cout << "~Farmer()--析构" << endl;
}

void Farmer::sow()
{
	cout << "Name= " << m_strName << endl;
	cout << "Farmer()--sow()" << endl;
}

 

 

//Worker.h

#pragma once
#include<iostream>
#include <string>
#include"Person.h"
using namespace std;
class Worker:public Person
{
public:
	Worker(string code = "Worker_001",string color="blue");
	virtual ~Worker();

	void carry();

protected:
	string m_strCode;
};
//Worker.cpp

#include<iostream>
#include"Worker.h"
using namespace std;

Worker::Worker(string code,string color):Person("Worker "+ color)
{
	m_strCode = code;
	cout << "Worker()--构造" << endl;
}

Worker::~Worker()
{
	cout << "~Worker()--析构" << endl;
}

void Worker::carry()
{
	cout << "Code= " << m_strCode << endl;
	cout << "Worker--carry()" << endl;
}

 

//MigrantWorker.h
#pragma once
#include<iostream>
#include <string>
#include"Worker.h"
#include"Farmer.h"
using namespace std;


class MigrantWorker :public Worker, public Farmer //继承两个类
{
public:
	MigrantWorker(string name, string code,string color);
	~MigrantWorker();
};
//MigrantWorker.cpp

#include"MigrantWorker.h"
using namespace std;
MigrantWorker::MigrantWorker(string name, string code,string color) :Farmer(name,color), Worker(code,color)
{
	cout << "MigrantWorker()--构造" << endl;
}


MigrantWorker::~MigrantWorker()
{
	cout << "~MigrantWorker()--析构" << endl;
}

 

//main.cpp

#include<iostream>
#include"MigrantWorker.h"
using namespace std;
/*************************

要求:虚继承  比较 使用虚继承和 不使用虚继承 之间的区别
1 定义Farmer类
	数据成员: m_strName
	成员函数:构造函数  析构函数 sow()

2 定义Worker类:
	数据成员: m_strCode
	成员函数:构造函数  析构函数  carry()

3 定义MigrantWorker类
	数据成员:无
	成员函数: 构造函数 析构函数

4 Person 
	数据成员: m_strColor
	成员函数:构造函数  析构函数 printColor()
**************************/

int main()
{
	MigrantWorker *p = new MigrantWorker("HAHA", "002","black");
	cout << "---------- 1 -----------" << endl;
	cout << "" << endl;

	p->Farmer::printColor();
	cout << "---------- 2 -----------" << endl;
	p->Worker::printColor();

	cout << "---------- 3 -----------" << endl;
	cout << "" << endl;

	delete p;
	p = NULL;


	cin.get();
	return 0;
}

 

上面没有使用虚继承的运行结果:

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

 

 

接下来 分别 在Farmer.hWorker.h 中加入 virtual 关键字(使用虚继承)

//Farmer.h  加入虚继承

#pragma once
#include<iostream>
#include <string>
#include"Person.h"
using namespace std;
class Farmer :virtual public Person//虚继承
{
public:
	Farmer(string name = "Farmer_001", string color = "blue");
	virtual ~Farmer();

	void sow();

protected:
	string m_strName;
};

//Worker.h 加入虚继承

#pragma once
#include<iostream>
#include <string>
#include"Person.h"
using namespace std;
class Worker:virtual public Person//虚继承
{
public:
	Worker(string code = "Worker_001",string color="blue");
	virtual ~Worker();

	void carry();

protected:
	string m_strCode;
};

 

运行结果:

C++ 继承(2): 多重继承, 多继承, 虚继承(virtual)

 

 


参考资料

[1] C++远征之继承篇  (注:图片均来自视频中PPT)

 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/15866.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信