通过一种机制表达类型之间的共性和特性的方式,利用已有的数据类型定义新的数据类型,这种机制就是继承。
人类:姓名 年龄 吃饭 睡觉
学生类:姓名 年龄 吃饭 睡觉 学习 学号
教师类:姓名 年龄 吃放 睡觉 讲课 工资
---------------------------------------
人类:姓名 年龄 吃饭 睡觉
学生类继承人类:学习 学号
教师类继承人类:讲课 工资
人类(基类/父类)
/ \
学生 教师(派生类/子类)
基类--派生-->子类
子类--继承-->基类
class 子类:继承方式 基类,...{
...
};
继承方式:
基类
↑
子类
eg:
class A{};
class B:public A{};
class C:public A{};
void func(A* pa){...}
B b;
func(&b);//向上造型
C c;
func(&c);//向上造型
#include
using namespace std;
//人类(基类)
class Human{
public:
Human(const string& name,int age)
:m_name(name),m_age(age),m_id(123){}
void eat(const string& food){
cout << "我在吃" << food << endl;
}
void sleep(int hour){
cout << "我睡了" << hour << "小时"
<< endl;
}
//保护的成员可以在类的内部和子类中访问
protected:
string m_name;
int m_age;
public:
//私有成员子类中无法直接访问,但是可以
//通过基类提供的接口函数间接访问
const int& getId(void)const{
return m_id;
}
private:
int m_id;
};
//学生类继承人类(人类派生的一个子类)
class Student:public Human{
public:
//:Human(..),指明基类部分的初始化方式
Student(const string& name,int age,
int no):Human(name,age),m_no(no){}
void learn(const string& course){
cout << "我在学" << course << endl;
}
void who(void){
cout << "我叫" << m_name << ",今年"
<< m_age << "岁,学号是" << m_no
<< endl;
cout << "身份证号:"<<getId() <<endl;
}
private:
int m_no;
};
//教师类继承人类(人类派生的另一个子类)
class Teacher:public Human{
public:
Teacher(const string& name,int age,
int salary):Human(name,age),
m_salary(salary){}
void teach(const string& course){
cout << "我在讲" << course << endl;
}
void who(void){
cout << "我叫" << m_name << ",今年"
<< m_age << "岁,工资是" <<
m_salary << endl;
}
private:
int m_salary;
};
int main(void)
{
Student s("关羽",29,10001);
s.who();
s.eat("红烧牛肉面");
s.sleep(8);
s.learn("孙武兵法");
Teacher t("悟空",30,50000);
t.who();
t.eat("水蜜桃");
t.sleep(6);
t.teach("Unix C编程");
//Student*-->Human*:向上造型
Human* ph = &s;
ph->eat("平谷大桃");
ph->sleep(2);
//ph->who();
//Human*-->Student*:向下造型(安全)
Student* ps = static_cast<Student*>(ph);
ps->who();
Human h("林黛玉",28);
//Human*-->Student*:向下造型(危险)
Student* ps2 =static_cast<Student*>(&h);
ps2->who();
return 0;
}
#include
using namespace std;
class Base{
public:
void func(void){
cout << "Base::func(void)" << endl;
}
};
class Derived:public Base{
public:
void func(int i){
cout << "Derived::func(int)" <<endl;
}
//将基类中func函数声明到当前子类,可以
//让其和子类中的func形成重载
//using Base::func;
};
int main(void)
{
Derived d;
d.Base::func();
d.func(10);
return 0;
}
访问控制 | 访问控制 | 内部 | 子类 | 外部 | 友元 |
---|---|---|---|---|---|
限定符 | 属性 | 访问 | 访问 | 访问 | 访问 |
public | 公有成员 | Ok | Ok | Ok | Ok |
protected | 保护成员 | Ok | Ok | No | Ok |
private | 私有成员 | Ok | No | No | Ok |
基类中的 | 在公有集成子类中变成 | 在保护集成子类中变成 | 在私有继承中子类变成 |
---|---|---|---|
公有成员 | 公有成员 | 保护成员 | 私有成员 |
保护成员 | 保护成员 | 保护成员 | 私有成员 |
私有成员 | 私有成员 | 私有成员 | 私有成员 |
class 子类:public 基类{
//基类(...):显式指明基类子对象初始化方式
子类(...):基类(...){}
};
#include
using namespace std;
class Member{
public:
Member(void):m_i(0){
cout << "Member(void)" << endl;
}
Member(int i):m_i(i){
cout << "Member(int)" << endl;
}
int m_i;
};
class Base{
public:
Base(void):m_i(0){
cout << "Base(void)" << endl;
}
Base(int i):m_i(i){
cout << "Base(int)" << endl;
}
int m_i;
};
class Derived:public Base{
public:
Derived(void){
cout << "Derived(void)" << endl;
}
//Base(i):指明基类子对象的初始化方式
//m_mem(i):指明成员子对象初始化方式
Derived(int i):Base(i),m_mem(i){
cout << "Derived(int)" << endl;
}
Member m_mem;//成员子对象
};
int main(void)
{
Derived d;
cout << d.m_i << ',' << d.m_mem.m_i
<< endl;//0,0
Derived d2(123);
cout << d2.m_i << ',' << d2.m_mem.m_i
<< endl;//123,123
return 0;
}
解决:虚析构函数
class A{};
class B:public A{};
A* pa = new B;//pa:指向子类对象的基类指针
delete pa;//有内存泄漏的风险
#include
using namespace std;
class Member{
public:
Member(void):m_i(0){
cout << "Member(void)" << endl;
}
Member(int i):m_i(i){
cout << "Member(int)" << endl;
}
~Member(void){
cout << "~Member(void)" << endl;
}
int m_i;
};
class Base{
public:
Base(void):m_i(0){
cout << "Base(void)" << endl;
}
Base(int i):m_i(i){
cout << "Base(int)" << endl;
}
~Base(void){
cout << "~Base(void)" << endl;
}
int m_i;
};
class Derived:public Base{
public:
Derived(void){
cout << "Derived(void)" << endl;
}
//Base(i):指明基类子对象的初始化方式
//m_mem(i):指明成员子对象初始化方式
Derived(int i):Base(i),m_mem(i){
cout << "Derived(int)" << endl;
}
~Derived(void){
cout << "~Derived(void)" << endl;
}
Member m_mem;//成员子对象
};
int main(void)
{
/* Derived d;
cout << d.m_i << ',' << d.m_mem.m_i
<< endl;//0,0
Derived d2(123);
cout << d2.m_i << ',' << d2.m_mem.m_i
<< endl;//123,123
*/
Base* pb = new Derived;
//...
//只调用基类的析构函数,有内存泄露风险
delete pb;
return 0;
}
class Base{};
class Derived:public Base{
//Base(that):显式的指明基类子对象也要以拷贝的方式来初始化
Derived(const Derived& that)
:Base(that),...{}
};
class Base{};
class Derived:public Base{
Derived& operator=(const Derived& that){
//显式调用基类的拷贝赋值函数
Base::operator=(that);
......
}
};
#include
using namespace std;
class Base{
public:
Base(void):m_i(0){}
Base(int i):m_i(i){}
Base(const Base& that):m_i(that.m_i){
cout << "Base(const Base&)" << endl;
}
Base& operator=(const Base& that){
cout << "Base::operator=" << endl;
if(&that != this){
m_i = that.m_i;
}
return *this;
}
int m_i;
};
class Derived:public Base{
public:
Derived(void):m_i(0){}
Derived(int i):Base(i),m_i(i){}
//Base(that):指明基类部分也要以拷贝方式
//来初始化
Derived(const Derived& that)
:m_i(that.m_i),Base(that){}
Derived& operator=(const Derived& that){
if(&that != this){
//显式调用基类的拷贝赋值函数,
//完成基类子对象的复制
Base::operator=(that);
m_i = that.m_i;
}
return *this;
}
int m_i;
};
int main(void)
{
Derived d1(123);
Derived d2(d1);//拷贝构造
cout << d1.m_i << ',' << d1.Base::m_i
<< endl;//123 123
cout << d2.m_i << ',' << d2.Base::m_i
<< endl;//123 123
Derived d3;
d3 = d1;//拷贝赋值
cout << d3.m_i << ',' << d3.Base::m_i
<< endl;//123 123
}
电话 播放器 计算机
\ | /
智能手机
#include
using namespace std;
//电话基类
class Phone{
public:
Phone(const string& number):
m_number(number){}
void call(const string& number){
cout << m_number << "打给" <<
number << endl;
}
private:
string m_number;
};
//播放器基类
class Player{
public:
Player(const string& media):
m_media(media){}
void play(const string& music){
cout << m_media << "播放器播放"
<< music << endl;
}
private:
string m_media;
};
//计算机基类
class Computer{
public:
Computer(const string& os):m_os(os){}
void run(const string& app){
cout << "在" << m_os << "系统上运行"
<< app << endl;
}
private:
string m_os;
};
//智能手机子类
class SmartPhone:public Phone,
public Player,
public Computer{
public:
SmartPhone(
const string& number,
const string& media,
const string& os):
Phone(number),
Player(media),
Computer(os){}
};
int main(void)
{
SmartPhone iphoneX(
"13866668888","MP4","Android");
iphoneX.call("010-110");
iphoneX.play("最炫小苹果.mp3");
iphoneX.run("Angry Brid");
SmartPhone* p1 = &iphoneX;
Phone* p2 = p1;
Player* p3 = p1;
Computer* p4 = p1;
cout << "p1=" << p1 << endl;
cout << "p2=" << p2 << endl;
cout << "p3=" << p3 << endl;
cout << "p4=" << p4 << endl;
return 0;
}
A
/ \
B C
\ /
D
#include
using namespace std;
class Base1{
public:
void func(void){
cout << "Base1::func(void)" << endl;
}
};
class Base2{
public:
void func(int i){
cout << "Base2::func(int)" << endl;
}
};
class Derived:public Base1,public Base2{
public:
//using Base1::func;
//using Base2::func;
};
int main(void)
{
Derived d;
d.Base1::func();
d.Base2::func(10);
return 0;
}
#include
using namespace std;
/* 钻石继承
* A(int m_data)
* / \
* B C
* \ /
* D(汇聚子类)
* */
class A{
public:
A(int data):m_data(data){
cout << "A:" << this << ","
<< sizeof(A) << endl;
}
protected:
int m_data;
};
class B:virtual public A{//虚继承
public:
B(int data):A(data){
cout << "B:" << this << "," <<
sizeof(B) << endl;
}
void set(int data){
m_data = data;
}
};
class C:virtual public A{//虚继承
public:
C(int data):A(data){
cout << "C:" << this << "," <<
sizeof(C) << endl;
}
int get(void){
return m_data;
}
};
class D:public B,public C{
public:
//虚继承,继承链最末端的汇聚子类负责
//构造公共基类子对象
D(int data):B(data),C(data),A(data){
cout << "D:" << this << "," <<
sizeof(D) << endl;
}
};
int main(void)
{
D d(100);
cout << d.get() << endl;//100
d.set(200);
cout << d.get() << endl;//200
return 0;
}
A(int m_data)
/ \
B C//:virtual public A
\ /
D//负责构造公共基类(A)子对象