一、菱形继承
代码演示:
创建: 1.Farmer类,数据成员:m_strName,成员函数:构造、析构、sow()
2.Worker类,数据成员:m_strCode,成员函数:构造、析构、carry()
3.MigrantWorker类,数据成员:无,成员函数:构造、析构
4.Person类,数据成员:m_strColor,成员函数:构造、析构、printColor()
派生关系:Person ->Farmer->MigrantWorker;Person ->Worker->MigrantWorker;Worker和Farmer->MigrantWorker
Person.h
#include<iostream>
#include<string>
using namespace std;
class Person
{
public:
Person(string color = "blue");
virtual ~Person();
void printColor();
protected:
string m_strColor;
};
Person.cpp
#include"Person.h"
Person::Person(string color)
{
m_strColor = color;
cout<<"Person()"<<endl;
}
Person::~Person()
{
cout<<"~Person()"<<endl;
}
void Person::printColor()
{
cout<<m_strColor<<endl;
cout<<"Person--printColor()"<<endl;
}
Farmer.h
#include"Person.h"
class Farmer:public Person
{
public:
Farmer(string name = "Jack",string color = "blue");
virtual ~Farmer();
void sow();
protected:
string m_strName;
};
Farmer.cpp
#include"Farmer.h"
Farmer::Farmer(string name,string color):Person("Farmer"+color)
{
m_strName = name;
cout<<"Farmer()"<<endl;
}
Farmer::~Farmer()
{
cout<<"~Farmer()"<<endl;
}
void Farmer::sow()
{
cout<<m_strName<<endl;
cout<<"Farmer--sow()"<<endl;
}
Worker.h
#include"Person.h"
class Worker:public Person
{
public:
Worker(string code = "001",string color = "blue");
virtual ~Worker();
void carry();
protected:
string m_strCode;
};
Worker.cpp
#include"Worker.h"
//为了证明在MigrantWorker类中已经存在了两份person的数据,将字符串worker也传递给Person,字符串之间可以拼接
Worker::Worker(string code,string color):Person("Worker"+color)//使用初始化列表将值向下进行传递,好处是如果Person当中有其他的逻辑,我们就不需要重复去写,而可以将值直接地传递给person的构造函数
{
m_strCode = code;
cout<<"Worker()"<<endl;
}
Worker::~Worker()
{
cout<<"~Worker()"<<endl;
}
void Worker::carry()
{
cout<<m_strCode<<endl;
cout<<"Worker--carry()"<<endl;
}
MigrantWorker.h
#include"Worker.h"
#include"Farmer.h"
class MigrantWorker:public Farmer,public Worker
{
public:
MigrantWorker(string name,string code,string color);
~MigrantWorker();
};
MigrantWorker.cpp
#include"MigrantWorker.h"
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"MigrantWorker.h"
int main(void)
{
MigrantWorker *p = new MigrantWorker("Merry","100","yellow");
p->Farmer::printColor();//在MigrantWorker类中已经存在了两份person的数据->解决用虚继承
p->Worker::printColor();
delete p;
p = NULL;
return 0;
}
运行结果:
因为MigrantWorker分别继承了Worker和Farmer,worker和farmer的头文件中都有person.h,所以MigrantWorker包含了两份person.h,造成重定义(即在当前工程中,person被声明了两遍)-->解决用宏定义-->在person.h中加上宏定义即可
在person.h中加上宏定义之后运行:
根据运行结果,发现在MigrantWorker类中已经存在了两份person的数据-->解决用虚继承
其余代码不变,将worker.h和farmer.h中继承方式前加上virtual关键字
Worker.h
#include"Person.h"
class Worker:virtual public Person//虚继承
{
public:
Worker(string code = "001",string color = "blue");
virtual ~Worker();
void carry();
protected:
string m_strCode;
};
Farmer.h
#include"Person.h"
class Farmer:virtual public Person
{
public:
Farmer(string name = "Jack",string color = "blue");
virtual ~Farmer();
void sow();
protected:
string m_strName;
};
运行结果:
使用了virtual关键字之后,就形成虚继承,好处:MigrantWorker所实例化的对象当中只有一份person的数据
运行结果为blue,说明在虚继承的情况下作为菱形继承最顶层的父类并没有进行参数的传递,参数只使用了顶层父类的默认参数,而无法从子类当中获得传入的参数。