大家好,欢迎来到IT知识分享网。
C++远征之继承篇 视频教程 笔记 方便自己查阅和复习,温故而知新。
接着 C++ 继承(1): 继承方式(public, protected, private), 继承中的特殊关系(隐藏 , is-a) 继续做笔记
目录
4 多继承与多重继承
4.1 多重继承
如下图示,士兵类 继承 人类 , 步兵类 继承 士兵类。我们称之为 这三者 属于 多重继承关系
我们还可以知道 这三者 相互之间 是 is-a 关系
在代码中 可以写为:
4.2 多继承
一个类有两个及以上的父类,称之为 多继承。注意区别前面的 多重继承。
在代码中 形式为:
代码示例
示例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;
}
运行结果:
示例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;
}
运行结果:
5 虚继承
上面的这种继承属于菱形继承,如果实例化对象D 那么D—>B—>A D—>C—>A , 此时D将会从A得到两个相同的数据,这属于数据冗余,是不能容忍的。
那么菱形继承 需要用 虚继承 来解决数据冗余的问题,格式如下图所示:
代码示例
要求:虚继承 比较 使用虚继承和 不使用虚继承 之间的区别
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;
}
上面没有使用虚继承的运行结果:
接下来 分别 在Farmer.h 和 Worker.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;
};
运行结果:
参考资料
[1] C++远征之继承篇 (注:图片均来自视频中PPT)
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/15866.html