C++继承篇基础知识

继承的不同方式:

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

/**
 * public公有继承方式
 */
class Worker: public Person { // 继承符号"子类 : 继承方式 父类"
//	class Worker: protected Person {
//		class Worker: private Person {
public:
	Worker();
	~Worker();
	void work();
	double mMoney;
};

#include "Worker.h"

Worker::Worker() {
	cout << "Worker()" << endl;
}

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

void Worker::work() {
	cout << "work()" << endl;
}

#include <iostream>
#include <string>
using namespace std;

class Person {
public:
	Person();
	~Person();
	void eat();
	string mName;
	int mAge;
};

#include "Person.h"

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

void Person::eat() {
	cout << "eat()" << endl;
}

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

/**
 * 	与java不同的是,C++的继承方式有三种
 *	分公有继承public ,保护继承 protected,私有继承private
 *	而java的继承则是公有继承public
 */
int main() {
	Worker worker;
	worker.eat();
	worker.work();
	cout << "继承篇" << endl;
	return 0;
}

公有继承public:

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

/**
 * public公有继承方式
 */
class Worker: public Person { // 继承符号"子类 : 继承方式 父类"
public:
	Worker();
	~Worker();
	void work();
	double mMoney;
	// 父类protected下的成员属性和成员函数都会集成到Worker的protected下
//	protected:
//	string mName;
//	int mAge;
};

#include "Worker.h"

Worker::Worker() {
	cout << "Worker()" << endl;
}

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

void Worker::work() {
	// 访问父类的protected成员函数和属性
	mName = "liugx";
	mAge = 27;
	cout << "work()" << "_mName = " << mName << "_mAge = " << mAge << endl;
}

#include <iostream>
#include <string>
using namespace std;

class Person {
public:
	Person();
	~Person();
	void eat();
protected:
	string mName;
	int mAge;
private:
//	int mAge;
};

#include "Person.h"

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

void Person::eat() {
	cout << "eat()" << endl;
}

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

/**
 * 继承方式:公有继承public,保护继承protected,私有继承private
 *
 * 与java不同的是,java只有公有继承方式,即是public方式,而且C++可以多继承
 */

/**
 * 外部类在非继承情况下只能访问一个cpp下面的public成员函数和属性,对于cpp下面的protected和private只能由该cpp才能访问
 */

/**
 * 公有继承方式:子类会继承父类public和protected下面的所有属性和成员到子类的public和protected下面
 *
 * private则会被继承到子类的不可见区域,注意不是在相应的private下面,所以子类也无法访问
 */
int main() {
	Worker worker;
	worker.mMoney = 5;
	worker.work();
//	worker.mAge = 27;//Person的protected mAge属性是继承在Worker的protected下面的,所以不能访问
	cout << "公有继承" << endl;
	return 0;
}

保护继承和私有继承方式:

#include <iostream>
#include <string>
using namespace std;

class Person {
public:
	Person();
	void play();
protected:
	string mName;
};

#include "Person.h"

Person::Person() {
	cout << "Person()" << endl;
}

void Person::play() {
	cout << "Person_play()" << "_name = " << mName << endl;
}

#include "Person.h"

/**
 * 继承方式protected和private
 */
//class Soldier: protected Person { // 继承符号"子类 : 继承方式 父类"
class Soldier: private Person { // 继承符号"子类 : 继承方式 父类"
public:
	Soldier();
	void work();
protected:
	double mAge;
private:
	//如果Soldier采用private私有继承Person,
//	则父类person的public:和protected:下面的属性和函数会继承到子类Soldier的private:下面
//	从而导致Soldier以下的子类无法访问到Person的public:和protected:下面的属性和函数

};

#include "Soldier.h"

Soldier::Soldier() {
	cout << "Soldier()" << endl;
}

void Soldier::work() {
	mName = "liugx";//访问父类成员属性
	mAge = 27;//访问自身属性成员
	cout << "Soldier_work()" << "_mName = " << mName << "_mAge = " << mAge << endl;
}

#include "Soldier.h"

class Infantry: public Soldier {
public:
	Infantry();
	void attack();
};

#include "Infantry.h"

Infantry::Infantry() {
	cout << "Infantry()" << endl;
}

void Infantry::attack() {
//	父类采用private继承之后,即是person类的mName和play()被继承到Soldier的private下面,所以Infantry类无法访问
	mName = "liuguangxi";
	play();
	cout << "attack()" << "_mName = " << mName << endl;
}

#include <iostream>
//#include "Soldier.h"
#include "Infantry.h"
using namespace std;

/**
 * 继承方式:公有继承public,保护继承protected,私有继承private
 *
 * 与java不同的是,java只有公有继承方式,即是public方式,而且C++还有保护继承protected,私有继承private,并且可以多继承
 */

/**
 * 外部类在非继承情况下只能访问一个cpp下面的public成员函数和属性,对于cpp下面的protected和private只能由该cpp才能访问
 */

/**
 * 1、public公有继承方式:子类会继承父类public和protected下面的所有属性和成员到子类的public和protected下面
 * private则会被继承到子类的不可见区域,注意不是在相应的private下面,所以子类也无法访问
 *
 * 2、protected保护继承方式:与公有继承方式不同的是父类public下面的属性和函数都会继承到子类的protected下面,
 * 父类private的继承效果则是同样效果
 *
 * 3、private私有继承方式:与公有继承方式不同的是父类public和protected下面的属性和函数都会继承到子类的private下面,
 * 父类private的继承效果则是同样效果(has a的关系)
 */
int main() {
//	Soldier soldier;
//	soldier.work();
//	soldier.play();
	Infantry infan;
	infan.attack();
	infan.work();
	cout << "继承" << endl;
	return 0;
}

多继承的使用:

//工人类
#include <iostream>
using namespace std;

class Worker {
public:
	Worker(int code);
	virtual ~Worker();
	void carry();
protected:
	int mCode;
};

//工人类
#include "Worker.h"

Worker::Worker(int code) :
		mCode(code) {
	cout << "Worker()" << endl;
}

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

void Worker::carry() {
//	mCode = 27;
	cout << "Worker_carry()_Code = " << mCode << endl;
}

//农名类
#include <iostream>
#include <string>
using namespace std;

class Farmer {
public:
	Farmer(string name);
	virtual ~Farmer();
	void show();
protected:
	string mName;
};

//农名类
#include "Farmer.h"

Farmer::Farmer(string name) :
		mName(name) {
	cout << "Farmer()" << endl;
}

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

void Farmer::show() {
//	mName = "Farmer_Name";
	cout << "show()_name = " << mName << endl;
}

//农名工类
#include "Worker.h"
#include "Farmer.h"

class MinrantWorker: public Worker, public Farmer {
public:
	MinrantWorker(string name, int code);
	virtual ~MinrantWorker();
};

//农名工类
#include "MigrantWorker.h"

MinrantWorker::MinrantWorker(string name, int code) :
		Worker(code), Farmer(name) {//初始化列表的时候可以初始化父类
	cout << "MinrantWorker()" << endl;
}

MinrantWorker::~MinrantWorker() {
	cout << "~MinrantWorker()" << endl;
}

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

/**
 * 多继承demo
 */
int main() {
	MinrantWorker mw("frame", 27);
	mw.show();
	mw.carry();
	cout << "C++多继承" << endl;
	return 0;
}

多重继承方式:

#include <iostream>
#include <string>
using namespace std;

class Person {
public:
	Person();
	~Person();
	void play();
protected:
	string mName;
};

#include "Person.h"

Person::Person() {
	cout << "Person()" << endl;
}

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


void Person::play() {
	cout << "Person_play()" << "_name = " << mName << endl;
}

#include "Person.h"

/**
 * 继承方式protected和private
 */
class Soldier: protected Person { // 继承符号"子类 : 继承方式 父类"
//class Soldier: private Person { 
public:
	Soldier();
	~Soldier();
	void work();
protected:
	double mAge;
private:
	//如果Soldier采用private私有继承Person,
//	则父类person的public:和protected:下面的属性和函数会继承到子类Soldier的private:下面
//	从而导致Soldier以下的子类无法访问到Person的public:和protected:下面的属性和函数

};

#include "Soldier.h"

Soldier::Soldier() {
	cout << "Soldier()" << endl;
}

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

void Soldier::work() {
	mName = "liugx";//访问父类成员属性
	mAge = 27;//访问自身属性成员
	cout << "Soldier_work()" << "_mName = " << mName << "_mAge = " << mAge << endl;
}

#include "Soldier.h"

class Infantry: public Soldier {
public:
	Infantry();
	~Infantry();
	void attack();
};

#include "Infantry.h"

Infantry::Infantry() {
	cout << "Infantry()" << endl;
}

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

void Infantry::attack() {
//	父类采用private继承之后,即是person类的mName和play()被继承到Soldier的private下面,所以Infantry类无法访问
	mName = "liuguangxi";
	play();
	cout << "attack()" << "_mName = " << mName << endl;
}

#include <iostream>
//#include "Soldier.h"
#include "Infantry.h"
using namespace std;

/**
 * 继承方式:公有继承public,保护继承protected,私有继承private
 *
 * 与java不同的是,java只有公有继承方式,即是public方式,而且C++还有保护继承protected,私有继承private,并且可以多继承
 */

/**
 * 外部类在非继承情况下只能访问一个cpp下面的public成员函数和属性,对于cpp下面的protected和private只能由该cpp才能访问
 */

/**
 * 1、public公有继承方式:子类会继承父类public和protected下面的所有属性和成员到子类的public和protected下面
 * private则会被继承到子类的不可见区域,注意不是在相应的private下面,所以子类也无法访问
 *
 * 2、protected保护继承方式:与公有继承方式不同的是父类public下面的属性和函数都会继承到子类的protected下面,
 * 父类private的继承效果则是同样效果
 *
 * 3、private私有继承方式:与公有继承方式不同的是父类public和protected下面的属性和函数都会继承到子类的private下面,
 * 父类private的继承效果则是同样效果(has a的关系)
 */

/**
 * 多重继承demo
 *
 * Infantry公有继承于Soldier,Soldier保护继承于Person
 */
int main() {
//	Soldier soldier;
//	soldier.work();
//	soldier.play();
	Infantry infan;
	infan.attack();
	infan.work();
	cout << "多重继承" << endl;
	return 0;
}

/*
 * 因为创建派生类对象时要调用基类的构造函数,当基类没有定义构函数时就调用默认无参数的构造函数。
 * 当只定义了有参的构造函数时就调用有参的构造函数,所以当派生类没有给基类传递参数时就会出现错误。
 * 解决方法:可以在基类中重载一个无参构造函数,或者给有参构造函数的参数设置默认值。
 */

继承的“隐藏”概念:

#include <iostream>
#include <string>
using namespace std;

class Person {
public:
	Person();
	void play();
protected:
	string mstrName;
	string mCode;
};

#include "Person.h"

Person::Person() {
	cout << "Person()" << endl;
}

void Person::play(){
	cout << "Person()_play()" << endl;
}

#include "Person.h"

class Soldier: public Person {
public:
	Soldier();
	void play(); //与person父类的函数同名   隐藏
	//void play(int x);//与上面的play()一样,都是隐藏与参数无关,只要函数名与父类的函数名称相同就是隐藏
	void work();
protected:
	int mCode;
};

#include "Soldier.h"

Soldier::Soldier() {
	cout << "Soldier()" << endl;
}

void Soldier::play() {
	cout << "Soldier()_play()" << endl;
}

void Soldier::work() {
	mCode = 16;// 访问的是Soldier的mCode
	Person::mCode = "18";// 访问的是Person的mCode
	cout << "Soldier()_work()" << endl;
}

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

/**
 * 关联篇:C++多态篇之虚函数表
 */

/**
 * 两个类父子关系,成员函数或者属性同名,则称之为隐藏
 */
int main() {
	Soldier soldier;
	soldier.play(); // 调用的是Soldier类的play函数
	soldier.Person::play(); // 调用的是Person类的play函数

	cout << "C++继承篇之隐藏" << endl;
	return 0;
}

虚继承使用方式:菱形继承概念

#ifndef PERSON_H //解决重定义
#define PERSON_H

#include <iostream>
#include <string>
using namespace std;

class Person {
public:
	Person();
	virtual ~Person();
	void printColor();
protected:
	string mColor;
};

#endif

#include "Person.h"

Person::Person() {
	cout << "Person()" << endl;
}

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

void Person::printColor() {
	mColor = "无色";
	cout << "Person_mColor = " << mColor << endl;
}

//工人类
#include "Person.h"

class Worker: public Person {
//class Worker: virtual public Person { // 虚继承于person
public:
	Worker(int code);
	virtual ~Worker();
	void carry();
protected:
	int mCode;
};

//工人类
#include "Worker.h"

Worker::Worker(int code) :
		mCode(code) {
	cout << "Worker()" << endl;
}

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

void Worker::carry() {
//	mCode = 27;
	cout << "Worker_carry()_Code = " << mCode << endl;
}

//农名类
#include "Person.h"

class Farmer: public Person {
//class Farmer: virtual public Person { // 虚继承于person
public:
	Farmer(string name);
	virtual ~Farmer();
	void show();
protected:
	string mName;
};

//农名类
#include "Farmer.h"

Farmer::Farmer(string name) :
		mName(name) {
	cout << "Farmer()" << endl;
}

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

void Farmer::show() {
//	mName = "Farmer_Name";
	cout << "show()_name = " << mName << endl;
}

//农名工类
#include "Worker.h"
#include "Farmer.h"

class MinrantWorker: public Worker, public Farmer {
public:
	MinrantWorker(string name, int code);
	virtual ~MinrantWorker();
};

//农名工类
#include "MigrantWorker.h"

MinrantWorker::MinrantWorker(string name, int code) :
		Worker(code), Farmer(name) { //初始化列表的时候可以初始化父类
	cout << "MinrantWorker()" << endl;
}

MinrantWorker::~MinrantWorker() {
	cout << "~MinrantWorker()" << endl;
}

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

/**
 * 多继承和多重继承同时存在时的困惑,菱形继承
 *
 * demo描述:农名工MinrantWorker多继承于农名类Farmer和工人类Worker
 * 但是农名类Farmer和工人类Worker又都继承于人类Person
 * 当我们在实例化农名工MinrantWorker时,即实现了两个多重继承
 * 那么就会多出一个person出来
 */

/**
 * 为解决上面的菱形继承带来的问题,C++引入虚继承解决方案,关键字virtual
 */
int main() {
	MinrantWorker mw("frame",27);
//	mw.printColor();//前提是类似菱形继承结构
//	如果父类不是虚继承于person,则子类MinrantWorker调用printColor()编译出错
//	因为编译器不知道调用哪个父类继承于person的printColor()
//	如果父类是虚继承于person,则子类MinrantWorker调用的printColor()是person的printColor()
	mw.Farmer::printColor();
	mw.Worker::printColor();
	cout << "C++虚继承" << endl;
	return 0;
}

C++对象的强制类型转换isA的应用方式:

#include <iostream>
#include <string>
using namespace std;

class Person {
public:
	Person();
//	~Person();
	virtual~Person();//虚析构函数,
	//作用:确保定义Person指针对象指向子类对象时候(Person *p = new Soldier())
	// delete Person时子类对象Soldier也会回调析构函数
	void play();
	string mstrName;
};

#include "Person.h"

Person::Person() {
	mstrName = "Person_name";
	cout << "Person()" << endl;
}

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

void Person::play() {
	cout << "Person()_play()" << "_name = " << mstrName << endl;
}

#include "Person.h"

class Soldier: public Person {
public:
	Soldier();
//	~Soldier();
	virtual~Soldier();//
	void work();
	int mCode;
	string mstrName;
};

#include "Soldier.h"

Soldier::Soldier() {
	mstrName = "Soldier_name";
	cout << "Soldier()" << endl;
}

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

void Soldier::work() {
	cout << "Soldier()_work()" << endl;
}

#include <iostream>
#include "Soldier.h"
//#include "Person.h"//无需再次include,因为Soldier.h里面已经包含
using namespace std;

void test1(Person p) {
	p.play();
}

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

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

/**
 * c++强制类型转换与java强制类型转换完全相同
 */
int main() {
//	Soldier s;
//	Person p = s;
//	p.play(); // p不能调用子类Soldier的work函数或者操作属性mCode
//	// play()输出的name是person初始化的name
//	Person *person = &s;
//	person->mstrName = "liugx";
//	person->play();
//
//	test1(p);
//	test1(s);
	// 参数传引用或者指针不会产生临时对象,效率更高
//	test2(p);
//	test2(s);
//	test3(&p);
//	test3(&s);

	Person *p1 = new Soldier();
	p1->play();
	delete p1;
	p1 = NULL; // 若父类person的析构函数不是虚析构函数,此时子类Soldier不回调析构函数会造成内存泄漏,这个问题需要虚析构函数解决

	cout << "C++强制类型转换" << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/u013171283/article/details/82954360