C++进阶——继承

devtools/2024/11/13 8:51:46/

前言:从这篇文章开始,我们进入C++进阶知识的分享,在此之前,我们需要先来回顾一个知识:

C++语言有三大特性,分别是封装、继承和多态,而我们前边所分享的各种容器类,迭代器等,它们所体现的就是封装

  • 将数据和方法放在一起,能够给用户访问就设为公有,不给用户访问就设为私有或保护。
  • 可以将一个类型放到另一个类型里边,通过typedef成员函数调整,封装出一个全新的类型。

这篇文章,我们将分享C++的第二大特性——继承


目录

一.何为继承

二.继承方式 

 三.继承关系

四.父类和子类对象赋值转换

五.继承中的作用域

六.派生类的默认构造函数

七.其他简单知识

总结


一.何为继承

举个例子:

在学校这一个大的教育机构中,有学生,老师,保安,宿管等等人员的存在。这些人的身份不同,那么就会有一些自己所独有的标签,比如学生有学生号,老师有职工号等。但是他们同时也都有共同的特性,比如姓名,年龄等等

他们有共同的标签,也有独有的标签,如果每个身份都要单独为他们创造标签,这样是不是过于繁琐,于是就有了继承的概念:

封装一个父(基)类,里边封装有这些人所具有的共同属性,比如姓名,年龄。随后通过父类继承出多个子(派生)类,子类既可以拥有父类中的属性,也可以自己建立自己独有的属性


二.继承方式 

class Person
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}string _name;//姓名int _age;//年龄
};class Student : public Person
{
protected:int _stuid;//学号
};
class Teacher : public Person
{
protected:int _jobid;//职工号
};

来看,Person作为父类,用于一个成员函数和两个成员变量Student和Teacher通过"public"方式继承父类,同时也拥有自己的成员变量。来看测试:

 

能够看出,子类能够使用父类中的成员变量而后成员函数。


 三.继承关系

在类中有public、protected、private三种访问方式。这些访问方式的不同,会影响到子类对父类中的成员变量和函数的访问

这三种访问方式可以理解为三级权限,public为低级权限,protected为中级权限,private为高级权限

这里给出最简单的理解方法,较低级的权限要向较高级的权限低头。 

前边在类的讲解中我们没有分享protected和private的区别,这里我们给出二者的区别:

父类的private成员在类外任何地方都不能被访问,包括派生类,而父类的protected成员可以在派生类中访问

一般情况下,public继承是最常用的

此外,我们知道struct也可以定义类,也可以继承父类,它与class的区别是:

  • struct默认的继承方式和访问限定符为public。
  • class默认的继承方式和访问限定符为private。

四.父类和子类对象赋值转换

通过标题,我们能够得出信息,父类对象和子类对象直接可以赋值,但是这里我先强调:只能由子类对象赋值给父类对象,而不能父类对象赋值给子类对象

直接来看例子:

要注意的是,父类对象只能得到自己继承下去的成员变量的信息,而不能得到子类自己的成员变量

除此之外,我们还可以通过父类对象的引用或指针来访问或修改子类对象的成员变量

因为父类对象中没有子类对象的成员变量,所以不能对其赋值。 


五.继承中的作用域

  1. 在继承体系中父类和子类都有独立的作用域
  2. 子类和父类中有同名成员在调用该成员时,子类会默认调用自己的成员,这种情况叫隐藏,也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问父类的同名成员
  3. 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏与参数无关
  4. 注意在实际中在继承体系里面最好不要定义同名的成员

来看实例:

class Person
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}string _name;//姓名int _age;//年龄int _num = 0;
};class Student : public Person
{
public:void fun(){cout << _num << endl;cout << Person::_num << endl;}
protected:int _stuid;//学号int _num = 1;
};

这里我们分别在Person和Student类中都定义了名为_num的成员变量,并在Student类中定义fun函数来打印二者,结果如下:

 

能够看出,默认情况下访问的是Student类自己的_num,加了域作用限定符后才会调用父类的_num。同名成员函数同理


六.派生类的默认构造函数

6个默认成员函数,“默认”的意思就是指我们不写,编译器会变我们自动生成一个,那么在派生类中,这几个成员函数是如何生成的呢?

  1. 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。
  2. 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
  3. 派生类的operator=必须要调用基类的operator=完成基类的复制。
  4. 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。
  5. 派生类对象初始化先调用基类构造再调派生类构造。
  6. 派生类对象析构清理先调用派生类析构再调基类的析构。

总结来说, 子类自己的成员变量调用自己的默认成员函数,而继承自父类的成员则需调用父类的默认成员函数父类没有的,就在子类中补充


七.其他简单知识

  1. 父类的友元,子类无法直接使用,但也可以将该友元定义在子类中,成为子类的友元。
  2. 父类的静态成员,与所有的子类共用。
  3. 一个子类可以同时继承多个父类,但是不推荐这样设计。

总结

关于继承的知识就分享这么多,喜欢本篇文章记得一键三连,我们下期再见!


http://www.ppmy.cn/devtools/5785.html

相关文章

type-cDP输入转双type-cDP输出,加type-c接口充电管理同时接两台显示器或者VR投屏,龙迅LT8712SX方案,龙迅桥接芯片方案

type-c的应用在各种设备上更加广泛&#xff0c;包括手机&#xff0c;电脑&#xff0c;游戏掌机&#xff0c; 因为type-c的功能非常强大&#xff0c;可以做到PD快充&#xff0c;DP信号输出&#xff0c;USB信号输出&#xff0c;所以很多设备为了做得更简洁都开始把其他的如HDMI接…

centos操作命令

CentOS操作命令包括但不限于以下几种&#xff1a; 系统操作命令&#xff1a; 关机、重启及登出&#xff1a; shutdown -h now&#xff1a;关闭系统。init 0 或 telinit 0&#xff1a;关闭系统。shutdown -r now&#xff1a;重启系统。reboot&#xff1a;重启系统。logout&…

iOS知识点 --- Runtime

Objective-C (OC) 中的 Runtime 原理&#xff1a; Objective-C Runtime 是一套用于支持 Objective-C 动态特性的底层 C 语言 API。它为 Objective-C 提供了以下核心功能&#xff1a; 动态类型&#xff1a;在运行时确定对象的确切类型&#xff0c;允许在程序执行过程中进行类型…

Swift错误处理

错误与异常的概念&#xff1a; 在Swift中&#xff0c;错误&#xff08;error&#xff09;表示程序可能遇到的意外情况&#xff0c;这些情况可能导致程序无法按预期的方式继续执行。错误通常表示由于外部因素或不正确的代码导致的问题。异常是一种特殊类型的错误&#xff0c;表…

第二届 Oceanbase 开发者大会 实录

第二届 Oceanbase 开发者大会 实录 今天很有幸参加了Oceanbase 开发者大会&#xff0c;我是真的我一开始还不知道什么是Oceanbase &#xff0c;直到我开了会才知道。看来真的需要多参加一些这样活动。 会议议程 我们科普一下什么是Oceanbase OceanBase 是阿里巴巴集团推出…

匿名函数lambda

一、匿名函数的基本语法 lambda 表达式可以看成是一般函数的函数名被略去,返回值使用了一个 -> 的形式表示。唯一与普通函数不同的是增加了捕获列表。[捕获列表](参数列表) -> 返回类型{函数体 }auto Add = [](int a, int b) -> int {return a + b; }; cout <<…

openssl3.2 - exp - 用base64后的字符串作为配置项的值

文章目录 openssl3.2 - exp - 用base64后的字符串作为配置项的值概述笔记配置项的值长度有限制 配置项的值不能是base64之后的直接值&#xff0c;需要处理之后才行。openssl配置项的值并不是所有可见字符都可以例子现在用的base64的类cipher_base64.hcipher_base64.cpp 现在用的…

kafka---topic详解

一、分区与高可用 在Kafka中,事件(events 事件即消息)是以topic的形式进行组织的;同时topic是分区(partitioned)的,这意味着一个topic分布在Kafka broker上的多个“存储桶”(buckets)上。这种数据的分布式放置对于可伸缩性非常重要,因为它允许客户端应用程序同时从多个…