继承的不同方式:
#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;
}