news 2026/5/1 14:26:43

【C++】从零认识C++的“继承”

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C++】从零认识C++的“继承”

一、继承的概念

继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许我们在保持原有类特性的基础上进行扩展,可以增加方法(成员函数)和属性(成员变量),这样产生的类,叫做派生类(或子类)。作为基础的原有类,称为基类(或父类)

二、定义与使用

1. 定义方式

继承的定义方式是:

代码语言:javascript

AI代码解释

class 派生类名 : 继承方式 基类名 {派生类内容};

假如定义一个Person类表示人,派生出一个Student类表示学生。Student包括Person的方法与属性,同时也有Student的独特方法与属性。那么就可以先定义出Person类,再继承出Student类:

代码语言:javascript

AI代码解释

class Person { public: Person() { cout << "Person()" << endl; } private: //名字 string name; }; class Student : public Person { public: Student() { cout << "Student()" << endl; } private: //学号 string id; };
2. 继承方式

继承方式有三种:public、private、protected。就是三种访问限定符,它们之间有什么关系呢?

基类成员的属性\派生类的继承方式

public继承后↓

protected继承后↓

private继承后↓

基类的public成员变成→

派生类的public成员

派生类的protected成员

派生类的private成员

基类的protected成员变成→

派生类的protected成员

派生类的protected成员

派生类的private成员

基类的prvate成员变成→

在派生类中不可见

在派生类中不可见

在派生类中不可见

哎,这里我们就看出来protected和private的区别了。

  • 总结一下上面的表格能发现,基类的private成员在派生类中都是不可见的。基类的其他成员在派生类中的访问方式为Min(在基类的访问限定符,继承方式),也就是两者里的较小者。其中public > protected > private。
  • 基类的private成员无论以什么方式继承,在派生类中都是不可见的。不可见指的是基类的private成员其实被继承到了派生类中,但是语法上限制派生类对象在类内或类外都不能去访问不可见成员。
  • 基类private成员在派生类中不能直接被访问。如果基类成员不想在类外被访问,但是想在派生类中能访问,就定义为protected,可以看出protected限定符是因继承才出现的。
  • 继承方式也可以不写,使用class关键字时默认的继承方式是private,使用struct时默认的继承方式是public。最好显式写出继承方式。
  • 在实际应用中我们一般都使用public继承,很少使用也不建议用protected和private继承,不利于代码维护。public继承能使基类和派生类中的接口访问方式保持一致。
3. 类模板的继承

类模板也是可以继承的。特殊的是,在定义派生类时,基类如果是类模板,必须指定类域,否则编译报错。

代码语言:javascript

AI代码解释

template<class T> class stack : public std::vector<T> //或者前面using namespace std; { public: void push(const T& x) { push_back(x); } };

三、基类和派生类的转换

public继承的派生类对象可以赋值给基类的指针或基类的引用,叫做赋值兼容转换,形象的说法是切片,就像把派生类中的基类那部分切割出来。基类指针或引用指向的是派生类中切出来的基类那部分。

在这里插入图片描述

比如:

代码语言:javascript

AI代码解释

class Person { public: Person() { cout << "Person()" << endl; } protected: string name = "zhangsan"; }; class Student : public Person { public: Student() { cout << Person::name << endl; } private: string id = "000001"; }; int main() { Student stu; Person* ptr = &stu; Person& ref = stu; //此时ptr和ref只指向和引用stu中属于基类的内容 return 0; }

注意:基类对象不能赋值给派生类对象。

四、基类和派生类的作用域

在继承体系中,基类和派生类都有各自独立的作用域,所以派生类和基类中可以有同名成员,但派生类中将屏蔽对基类的同名成员的直接访问,这种情况叫做隐藏。若想访问基类的这个成员,需要写成基类::基类成员显式访问。 需要知道的是,如果是基类和派生类的成员函数,只要函数名相同,就构成隐藏。不过,在实际应用继承体系中,我们最好就不要定义同名的成员了。

代码语言:javascript

AI代码解释

class A { protected: int x; }; class B : public A { public: test() { //直接访问不到基类的同名成员 cout << x << endl; //必须指定类域才能访问 cout << A::x << endl; } protected: int x; };

再来看一个例子:

代码语言:javascript

AI代码解释

class A { public: void func(int x) { cout << "func(int x)" << endl; } }; class B : public A { public: void func() { cout << "func()" << endl; } };

基类A和派生类B中有同名函数,虽然参数列表不同,但是还是构成隐藏关系。直接访问func只会调到派生类的func:

在这里插入图片描述

若想访问到基类的func,也要指定类域:

在这里插入图片描述

五、派生类的默认成员函数

类有默认成员函数的概念,派生类也有。最重要的是要理解:基类成员的初始化、清理等行为都是作为一个整体来完成的。

  • 派生类的构造函数必须要调用基类的构造函数,来初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类的构造函数的初始化列表阶段显式调用。而派生类对象初始化时,先调用基类构造,再调派生类构造。
  • 派生类的析构函数会在被调用完成后自动调用基类的析构函数,因为这样才能保证派生类对象先清理派生类成员,再清理基类成员的顺序。派生类析构函数和基类析构函数构成隐藏关系,这涉及到多态的知识。
  • 派生类的拷贝构造函数,必须调用基类的拷贝构造函数,完成基类成员的拷贝初始化。
  • 派生类的operator=必须要调用基类的operator=,完成基类的复制。需要注意的是,派生类的operator=和基类的operator=构成隐藏关系,所以显式调用基类的operator=时需要指定基类作用域。

www.dongchedi.com/article/7597158211648979481
www.dongchedi.com/article/7597159849193439769
www.dongchedi.com/article/7597158216006861336
www.dongchedi.com/article/7597158526565302808
www.dongchedi.com/article/7597157528921031193
www.dongchedi.com/article/7597157528921129497
www.dongchedi.com/article/7597158828748390937
www.dongchedi.com/article/7597157605437768216
www.dongchedi.com/article/7597157947516748350
www.dongchedi.com/article/7597157059532309016
www.dongchedi.com/article/7597157528921195033
www.dongchedi.com/article/7597157918697554456
www.dongchedi.com/article/7597158225347412542
www.dongchedi.com/article/7597154994248679961
www.dongchedi.com/article/7597156908373656088
www.dongchedi.com/article/7597155389817848344
www.dongchedi.com/article/7597156872139178558
www.dongchedi.com/article/7597156044007031320
www.dongchedi.com/article/7597154815566905881
www.dongchedi.com/article/7597156083979321918
www.dongchedi.com/article/7597154815567233561
www.dongchedi.com/article/7597155548034925081
www.dongchedi.com/article/7597153356364497433
www.dongchedi.com/article/7597155446209643033
www.dongchedi.com/article/7597153704529101336
www.dongchedi.com/article/7597155329252049470
www.dongchedi.com/article/7597153135701885465
www.dongchedi.com/article/7597153238500491838
www.dongchedi.com/article/7597153219835724350
www.dongchedi.com/article/7597152705005535806
www.dongchedi.com/article/7597152321495679513
www.dongchedi.com/article/7597153608114995774
www.dongchedi.com/article/7597153135702147609
www.dongchedi.com/article/7597153201120559640
www.dongchedi.com/article/7597152939333354008
www.dongchedi.com/article/7597153929230828094
www.dongchedi.com/article/7597151125615264281
www.dongchedi.com/article/7597151505988207166
www.dongchedi.com/article/7597153085034889752
www.dongchedi.com/article/7597151163980497432
www.dongchedi.com/article/7597144704257835545
www.dongchedi.com/article/7597144998823641624
www.dongchedi.com/article/7597145929174991384
www.dongchedi.com/article/7597145158681231896
www.dongchedi.com/article/7597144871509443096
www.dongchedi.com/article/7597144629225505342
www.dongchedi.com/article/7597142612923040281
www.dongchedi.com/article/7597142227030196761
www.dongchedi.com/article/7597142612923335193
www.dongchedi.com/article/7597143374680359486
www.dongchedi.com/article/7597143842856485400
www.dongchedi.com/article/7597143131083342361
www.dongchedi.com/article/7597143126788555289
www.dongchedi.com/article/7597138911823086105
www.dongchedi.com/article/7597139690651009561
www.dongchedi.com/article/7597137695479087678
www.dongchedi.com/article/7597137790945575448
www.dongchedi.com/article/7597139271543407129
www.dongchedi.com/article/7597137533486989848
www.dongchedi.com/article/7597138669631390232
www.dongchedi.com/article/7597100744432910873
www.dongchedi.com/article/7597101277981491736
www.dongchedi.com/article/7597101132292637209
www.dongchedi.com/article/7597091310348403262

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/29 14:34:09

SpringBoot 配置文件

SpringBoot 的核心特性之一是自动配置&#xff0c;而配置文件是定制化自动配置的核心入口。本文结合实操代码&#xff0c;详细讲解 SpringBoot 配置文件的类型、语法、数据绑定等核心知识点。一、配置文件基础1. 配置文件类型SpringBoot 支持两种主流配置文件格式&#xff0c;默…

作者头像 李华
网站建设 2026/5/1 8:56:18

5分钟上手GLM-TTS,零基础实现方言语音克隆

5分钟上手GLM-TTS&#xff0c;零基础实现方言语音克隆 1. 引言&#xff1a;为什么你需要关注GLM-TTS&#xff1f; 在内容创作、虚拟人交互和有声读物快速发展的今天&#xff0c;个性化语音合成正从“可选功能”变为“核心竞争力”。传统TTS&#xff08;文本转语音&#xff09…

作者头像 李华
网站建设 2026/4/29 14:35:11

一键启动Sambert:多情感语音合成零配置部署

一键启动Sambert&#xff1a;多情感语音合成零配置部署 1. 引言&#xff1a;多情感语音合成的工程落地挑战 在智能客服、有声阅读、虚拟主播等应用场景中&#xff0c;传统语音合成系统往往只能提供“机械朗读”式的输出&#xff0c;缺乏情绪表达和语调变化。随着深度学习技术…

作者头像 李华
网站建设 2026/5/1 2:29:08

小米MiMo-Audio:7B音频大模型开启声音学习新范式!

小米MiMo-Audio&#xff1a;7B音频大模型开启声音学习新范式&#xff01; 【免费下载链接】MiMo-Audio-7B-Base 项目地址: https://ai.gitcode.com/hf_mirrors/XiaomiMiMo/MiMo-Audio-7B-Base 小米正式发布全新音频大模型MiMo-Audio-7B-Base&#xff0c;通过创新的&quo…

作者头像 李华
网站建设 2026/4/23 17:36:53

PyTorch-2.x-Universal镜像带来极致开发体验,看完就想试

PyTorch-2.x-Universal镜像带来极致开发体验&#xff0c;看完就想试 1. 引言&#xff1a;为什么你需要一个高效的深度学习开发环境&#xff1f; 在现代深度学习项目中&#xff0c;模型训练和微调只是整个工作流的一环。更常见的情况是&#xff1a;你花费大量时间在环境配置、…

作者头像 李华
网站建设 2026/5/1 2:29:20

BilibiliSponsorBlock完全攻略:5分钟配置让B站观看体验焕然一新

BilibiliSponsorBlock完全攻略&#xff1a;5分钟配置让B站观看体验焕然一新 【免费下载链接】BilibiliSponsorBlock 一款跳过B站视频中恰饭片段的浏览器插件&#xff0c;移植自 SponsorBlock。A browser extension to skip sponsored segments in videos on Bilibili.com, port…

作者头像 李华