C++初始继承,继承中构造、析构顺序

2. C++ 中的继承是⾯向对象编程的三⼤特性之⼀。

有些类与类之间存在着特殊的关系,例如下图:

我们发现,定义这些类时,下级别的成员除了拥有上⼀级的共性(特征+⾏为),还有⾃⼰的特性 (特征+⾏为)。

这个时候我们就可以考虑利⽤继承的技术。允许⼀个类(⼦类****/**** 派⽣类)继承另⼀个类(⽗类****/**** 基类)的属性和⽅法,从⽽实现代码复⽤和层次化设计。(继承允许从已有类(基类 / ⽗类)派⽣出新类(派⽣类 / ⼦类),⼦类可复⽤⽗类的成员并扩展新功能,减少代码冗余。)简单来说,继承就像:⼉⼦会继承⽗亲的某些特征(如眼睛颜⾊、⾝⾼)学⽣是⼈的⼀种,会继承 "⼈" 的基本属性(姓名、年龄),同时有⾃⼰的特有属性(学号、班级)

2.7.1 基本语法

继承⽅式: public (公有继承)、 protected (保护继承)、 private (私有继承),常⽤ public

⼦类成员包含:从⽗类继承的成员(⾮私有) + ⼦类新增的成员

2.7.2 ⽰例

例如我们看到很多⽹站中,都有公共的头部,公共的底部,甚⾄公共的左侧列表,只有中⼼内容不同。

接下来我们分别利⽤普通写法和继承写法来实现⽹⻚中的内容,看⼀下继承存在的意义以及好处。

2.7.2.1 普通实现

class 子类名 : 继承方式 父类名

{

// 子类成员

}

#include <iostream>

#include <string>

#include <iomanip>

using namespace std;

// Java方向对应的页面

class Java

{

public:

// 头部

void header()

{

cout << "首页、公开课、登录、注册...(公共头部)" << endl;

}

// 底部

void footer()

{

cout << "帮助中心、交流合作、版权信息、站内导航...(公共底部)" << endl;

}

// 左侧菜单

void left()

{

cout << "Java、Web、C++...(公共分类列表)" << endl;

}

// 右侧内容

void content()

{

cout << "Java大纲、Java学习视频、Java讲师介绍" << endl;

}

};

// Web方向对应的页面

class Web

{

public:

// 头部

void header()

{

cout << "首页、公开课、登录、注册...(公共头部)" << endl;

}

// 底部

void footer()

{

cout << "帮助中心、交流合作、版权信息、站内导航...(公共底部)" << endl;

}

// 左侧菜单

void left()

{

cout << "Java、Web、C++...(公共分类列表)" << endl;

}

// 右侧内容

void content()

{

cout << "Web大纲、Web学习视频、Web讲师介绍" << endl;

}

};

// C++方向对应的页面

class CPP

{

public:

// 头部

void header()

{

cout << "首页、公开课、登录、注册...(公共头部)" << endl;

}

// 底部

void footer()

{

cout << "帮助中心、交流合作、版权信息、站内导航...(公共底部)" << endl;

}

// 左侧菜单

void left()

{

cout << "Java、Web、C++...(公共分类列表)" << endl;

}

// 右侧内容

void content()

{

cout << "C++大纲、C++学习视频、C++讲师介绍" << endl;

}

};

int main(int argc, char **argv)

{

// Java方向

cout << "Java方向:" << endl;

Java ja;

ja.header();

ja.footer();

ja.left();

ja.content();

cout << "------------------" << endl;

// Web方向

cout << "Web方向:" << endl;

Web we;

we.header();

we.footer();

we.left();

we.content();

cout << "------------------" << endl;

// C++方向

cout << "C++方向:" << endl;

CPP cp;

2.7.2.2 继承实现

cp.header();

cp.footer();

cp.left();

cp.content();

cout << "------------------" << endl;

return 0;

}

#include <iostream>

#include <string>

#include <iomanip>

using namespace std;

// 将Java、Web、CPP中相同的代码提取到父类中

class BasePage

{

public:

// 头部

void header()

{

cout << "首页、公开课、登录、注册...(公共头部)" << endl;

}

// 底部

void footer()

{

cout << "帮助中心、交流合作、版权信息、站内导航...(公共底部)" << endl;

}

// 左侧菜单

void left()

{

cout << "Java、Web、C++...(公共分类列表)" << endl;

}

};

// 子类:Java方向对应的页面

class Java : public BasePage

{

public:

// 右侧内容

void content()

{

cout << "Java大纲、Java学习视频、Java讲师介绍" << endl;

}

};

// 子类:Web方向对应的页面

class Web : public BasePage

{

public:

// 右侧内容

void content()

{

cout << "Web大纲、Web学习视频、Web讲师介绍" << endl;

}

};

// 子类:C++方向对应的页面

class CPP : public BasePage

{

public:

// 右侧内容

void content()

{

cout << "C++大纲、C++学习视频、C++讲师介绍" << endl;

}

};

int main(int argc, char **argv)

{

// Java方向

cout << "Java方向:" << endl;

Java ja;

ja.header();

ja.footer();

ja.left();

ja.content();

cout << "------------------" << endl;

// Web方向

cout << "Web方向:" << endl;

Web we;

we.header();

we.footer();

we.left();

2.7.3 继承的好处

代码复⽤:减少重复代码,⽗类的成员可被多个⼦类共享扩展⽅便:⼦类可在⽗类基础上新增功能,⽆需修改⽗类代码

2.7.4 继承⽅式

继承的语法:

继承⽅式⼀共有三种:

公共继承【 : public 】,常⽤

保护继承【 : protected 】

私有继承【 : private 】

⽰例:

we.content();

cout << "------------------" << endl;

// C++方向

cout << "C++方向:" << endl;

CPP cp;

cp.header();

cp.footer();

cp.left();

cp.content();

cout << "------------------" << endl;

return 0;

}

class 子类 : 继承方式 父类{..}

#include <iostream>

#include <string>

#include <iomanip>

using namespace std;

// 父类

class Base1

{

public:

int public_A;

protected:

int protected_A;

private:

int private_A;

};

// 子类 公共继承(常用)

class Son1 : public Base1

{

public:

// 子类成员 访问父类成员

void func()

{

public_A = 10; // 派生类可访问父类 public 权限

protected_A = 20; // 派生类可访问父类 protected 权限

// private_A = 30; // 派生类不可访问父类 private 权限

}

};

// 外部访问测试

void test01()

{

Son1 s;

s.public_A = 100; // 类外部可访问 public 权限:类内部、派生类、类

外部均可访问

// s.protected_A = 200; // 类外部不可访问 protected 权限:类内部、派生类可

访问,类外部不可访问

// s.private_A = 300; // 类外部不可访问 private 权限:类内部可访问,派生

类和类外部不可访问

}

// ---------------------------------------------------------

// 子类 保护继承

class Son2 : protected Base1

{

public:

// 子类成员 访问父类成员

void func()

{

public_A = 10; // 派生类可访问父类 public 权限

protected_A = 20; // 派生类可访问父类 protected 权限

// private_A = 30; // 派生不可访问父类 private 权限

}

};

// 外部访问测试

void test02()

{

Son2 s;

// s.public_A = 100; // 类外部不可访问 public 权限:类内部、派生类、类

外部均可访问

// s.protected_A = 200; // 类外部不可访问 protected 权限:类内部、派生类可

访问,类外部不可访问

// s.private_A = 300; // 类外部不可访问 private 权限:类内部可访问,派生

类和类外部不可访问

}

// ----------------------------------------------

// 子类 私有继承

class Son3 : private Base1

{

public:

// 子类成员 访问父类成员

void func()

{

public_A = 10; // 派生类可访问父类 public 权限

protected_A = 20; // 派生类可访问父类 protected 权限

// private_A = 30; // 派生不可访问父类 private 权限

}

};

// 外部访问测试

void test03()

{

Son3 s;

// s.public_A = 100; // 类外部不可访问 public 权限:类内部、派生类、类

外部均可访问

// s.protected_A = 200; // 类外部不可访问 protected 权限:类内部、派生类可

访问,类外部不可访问

2.7.5 继承中构造和析构顺序

⼦类继承⽗类后,当创建⼦类对象的时候,也会调⽤⽗类构造函数。

问题:⽗类和⼦类的构造和析构顺序谁先谁后?

⽰例:

// s.private_A = 300; // 类外部不可访问 private 权限:类内部可访问,派生

类和类外部不可访问

}

int main(int argc, char **argv)

{

return 0;

}

#include <iostream>

#include <string>

#include <iomanip>

using namespace std;

// 定义父类

class Base

{

public:

Base()

{

cout << "Base构造函数" << endl;

}

~Base()

{

cout << "Base析构函数" << endl;

}

};

运⾏结果:

总结:继承中 先调⽤⽗类构造函数,再调⽤⼦类构造函数,析构顺序和构造相反。

相关推荐
运维管理2 小时前
Linux系统笔记--Base
开发语言·php
全栈软件开发2 小时前
最新版T5友价互站网源码商城PHP源码交易平台 完整带手机版源码网系统源码
android·开发语言·php
Mos_x2 小时前
关于我们的python日记本
开发语言·python
The Sheep 20232 小时前
Dotnet-Dapper的用法
java·开发语言
十重幻想3 小时前
reshape的共享内存
python
Juchecar3 小时前
设计模式不是Java专属,其他语言的使用方法
java·python·设计模式
马克学长3 小时前
SSM基于Java的医疗器械销售系统oy281(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·开发语言·用户管理·ssm 框架·医疗器械销售系统
scala舔狗汪3 小时前
双层跳动爱心❤️❤️💕💕
python
lqj_本人3 小时前
Rust与Go:现代系统编程语言的深度对比
开发语言·golang·rust