C++:继承:面向对象编程的重要特性

在这里插入图片描述
(❁´◡❁)(●'◡'●)╰(*°▽°*)╯(*/ω\*)(^///^)(❁´◡❁)(❁´◡❁)(●'◡'●)╰(*°▽°*)╯(*/ω\*)(❁´◡❁)(●’◡’●)╰(°▽°)╯(/ω\)(///)

C++:继承:面向对象编程的重要特性

    • 前言
    • **继承**
      • 1.继承的概念及定义
        • 1.1继承的概念
        • 1.2继承的定义
          • 1.2.1定义的格式
          • 1.2.2继承关系和访问限定符
          • 1.2.3继承后基类(父类)成员访问方式的变化
      • 2.基类和派生类对象赋值转换
      • 3.继承中的作用域
      • 4.派生类的默认成员函数
      • 5.继承与友元
      • 6. 继承与静态成员
      • 7.多继承与菱形继承和菱形虚拟继承

🎉文章简介:

🎉本篇文章将 C++继承,全特化,偏特化,非类型模板参数,模板的分离编译 相关知识进行分享!
💕如果您觉得文章不错,期待你的一键三连哦!!!

前言

在这篇文章中,你可以学习到继承作为面向对象编程的重要特性,它允许一个类(子类)继承另一个类(父类)的属性和方法。
在文章中涵盖的主要内容:
继承的概念,继承的语法,继承的作用,单继承,多继承,菱形继承,菱形虚拟继承,菱形虚拟继承与菱形继承在内存中的差异等。

继承

1.继承的概念及定义

1.1继承的概念

继承是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。简单地说就是类的复用;

1.2继承的定义
1.2.1定义的格式

举个栗子(下附代码):
在这里插入图片描述
代码段:

class Person
{
protected:  string _name;int _age;string _sex;int _tel;
};
class student:public Person     //student继承了Person这个类
{
protected:int _id;
};
1.2.2继承关系和访问限定符

在这里插入图片描述

1.2.3继承后基类(父类)成员访问方式的变化
类成员/继承方式public继承protected继承private继承
基类的public成员派生类的public成员派生类的protected成员派生private成员
基类的protected成员派生类的protected成员派生类的protected成员派生类的private成员
基类的private成员在派生类中不可见在派生类中不可见在派生类中不可见

总结:

1.基类的private成员在派生类中无论以什么方式继承都是不可见的,这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它;

2.基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的;

3.实际上面的表格我们进行一下总结会发现,基类的私有成员在子类都是不可见。基类的其他成员在子类的访问方式 == Min(成员在基类的访问限定符,继承方式)public > protected > private;

4.使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式;

5.在实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡使用protetced/private继承,因为protetced/private继承下来的成员都只能在派生类的类里面使用,实际中扩展维护性不强;

举个栗子:
在这里插入图片描述
从上面例子可以看出,private继承后,public,protected成员在派生类可以访问,private成员不可访问;

2.基类和派生类对象赋值转换

派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用。这里有个形象的说法叫切片或者切割
基类对象不能赋值给派生类对象。
基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。注意:但是必须是基类的指针是指向派生类对象时才是安全的。这里基类如果是多态类型,会有特殊处理(后面的文章会提到);

在这里插入图片描述

class Person
{
protected:  string _name;int _age;string _sex;int _tel;
};
class student:public Person
{
protected:int _id;
};int main()
{student s1;Person p1;p1 = s1;//s1 = p1;   //这里不能基类给派生类Person& pp1 = s1;     //是对截断后的内容引用Person* pp2 = &s1;     //指向的是截断后的内容student* ss;ss = (student*)&p1;         //基类的指针可以通过强制类型转换赋值给派生类的指针return 0;
}

在这里插入图片描述

3.继承中的作用域

1. 在继承体系中基类和派生类都有独立的作用域
(就凭这一点,因此两个域中的函数不能构成函数重载
2. 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)
3. 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏
4. 注意在实际中在继承体系里面最好不要定义同名的成员。

4.派生类的默认成员函数

派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。(先父后子)
派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
派生类的operator=必须要调用基类的operator=完成基类的复制。
派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。(先子后父)
编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加virtual的情况下,子类析构函数和父类析构函数构成隐藏关系。
如果要显示调用,需要指定作用域;

5.继承与友元

友元关系不能被继承,也就是说基类友元不能访问子类私有和保护成员

举个例子:
在这里插入图片描述

6. 继承与静态成员

基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。因为静态成员函数不是放在类里面的,而是放在静态区的,是这个类的对象所公有的,无论派生出多少个子类,都只有一个static成员实例 ;
利用这个特性,可以统计这个类被创建了多少个对象;
如果被继承了,无论派生类实例化出对象了还是基=基类实例化出对象都会调用基类的构造函数,就可以统计出个数;

例子:


class Person
{
public:Person(){_count++;}
protected:  int _age;
public:static int _count;
};
int Person::_count = 0;class student:public Person
{
public:student(){}
protected:int _id;
};int main()
{student S1;student S2;Person P1;Person P2;cout << Person::_count << endl;    //打印结果为4return 0;
}

7.多继承与菱形继承和菱形虚拟继承

单继承:一个子类只有一个直接父类时称这个继承关系为单继承
在这里插入图片描述
多继承:一个子类只有多个直接父类时称这个继承关系为多继承

在这里插入图片描述

菱形继承:
在这里插入图片描述

菱形继承的问题:菱形继承有数据冗余二义性的问题。在D的对象中A成员会有两份。因为B,C中都继承了A,里面各有一份A,然后D继承了B和C,所以会有两份A;

因为有两份,所以数据冗余了,又因为D里面有两份A的成员,如果想通过D实例化的对象去访问B中继承的A的成员时,不知道是去访问B的还是C的;结合下面例子看看:

结合下面代码:
在这里插入图片描述

class A
{
public:int _a;
};
class B:public A
{
protected:int _b;
};
class C:public A
{
protected:int _c;
};
class D:public B, public C
{
protected:int _d;
};
int main()
{D dd;//dd._a = 10;      //会报错(访问不明确)dd.B::_a = 10;dd.C::_a = 100;     //这样指定类域访问也可以,但是代码稍许冗余return 0;
}

解决方法:

虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在B和C的继承A时使用虚拟继承,即可解决问题。需要注意的是,虚拟继承不要在其他地方去使用。

解决后的代码:

class A
{
public:int _a;
};
class B:virtual public A    /这里+
{
protected:int _b;
};
class C:virtual public A   //这里+
{
protected:int _c;
};
class D:public B, public C
{
protected:int _d;
};

在哪里+virtual的问题

在造成数据冗余的那两个类的继承方式前面加virtual

比如:
在这里插入图片描述

菱形继承虚拟菱形继承在内存上的差异
我们讨论的是VS上

D对象中将A放到的了对象组成的最下面,这个A同时属于B和C,那么B和C如何去找到公共的A呢?这里是通过了B和C的两个指针,指向的一张表。这两个指针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量可以找到下面的A。
在这里插入图片描述
(❁´◡❁)(●'◡'●)╰(*°▽°*)╯(*/ω\*)(^///^)(❁´◡❁)(●’◡’●)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/280469.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis6.0多线程的疑惑解答

1.Redis6.0之前的版本真的是单线程吗&#xff1f; Redis在处理客户端的请求是&#xff0c;包括获取(socket读)、解析、执行、内容返回(socket 写)等都有一个 顺序串行的主线程处理&#xff0c;这就是所谓的"单线程"。但如果严格来讲并不是单线程&#xff0c;除了主线…

SpringMVC学习笔记

SpringMVC 本篇笔记是基于尚硅谷学习资料的整理&#xff0c;涉及到其笔记的简化&#xff0c;补充&#xff0c;以及我在学习中遇到的与无法理解的问题及解决&#xff0c;如果想看完整及后续的笔记&#xff0c;可以去https://www.wolai.com/v5Kuct5ZtPeVBk4NBUGBWF查看官方笔记。…

演讲嘉宾公布 | 3D音频专题论坛将于3月27日举办

一、3D音频专题论坛 3D音频技术不仅能够提供更加真实、沉浸的虚拟世界体验&#xff0c;跨越时空的限制&#xff0c;探索未知的世界。同时&#xff0c;提供更加丰富、立体的情感表达和交流方式&#xff0c;让人类能够更加深入地理解彼此&#xff0c;建立更加紧密的联系。3D音频未…

MongoDB系列之查询计划

概述 一个查询具体如何被执行的过程&#xff0c;称为查询计划。MongoDB采用自底向上的方式来构造查询计划&#xff0c;每一个查询计划&#xff08;query plan&#xff09;都会被分解为若干个有层次的阶段&#xff08;stage&#xff09;。整个查询计划最终会呈现出一颗多叉树。…

Windows管理多版本nodejs方法

参考&#xff1a;window操作系统安装多个版本的nodejs——nodejs版本控制工具nvm_windows node多版本共存-CSDN博客 前排&#xff1a; 建议把原来电脑装的nodejs卸载干净&#xff0c;再干这个步骤&#xff0c;可以避免出现一些状况&#xff1b;&#xff1b;&#xff1b;另&…

免费PDF转换和编辑工具 PDFgear 2.1.4

PDFgear是一款功能强大的 PDF 阅读及转换软件。 它支持多种文件格式的转换和编辑&#xff0c;同时还提供了丰富的功能模块&#xff0c;如签名、表单填写等&#xff0c;方便用户进行多样化的操作。 该软件界面简洁美观&#xff0c;操作简单易懂&#xff0c;适合不同层次的用户…

【论文阅读】通过组件对齐评估和改进 text-to-SQL 的组合泛化

Measuring and Improving Compositional Generalization in Text-to-SQL via Component Alignment NAACL 2022| CCF B Abstract 在 text-to-SQL 任务中&#xff0c;正如在许多 NLP 中一样&#xff0c;组合泛化是一个重大挑战&#xff1a;神经网络在训练和测试分布不同的情况…

iostream、fstream、sstream、string、vector、unordered_map、stack

iostream 用于输入输出操作&#xff0c;包含了处理标准输入输出流的功能&#xff08;例如&#xff0c;cin, cout, cerr等&#xff09;。 #include <iostream>int main() {int number;std::cout << "Enter a number: ";std::cin >> number;std::…

基于Springboot的防疫物资管理信息系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的防疫物资管理信息系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

docker部署grafana graphite stastd实时监控告警配置_亲测成功

docker部署grafana graphite stastd实时监控告警配置_亲测成功 实时监控请求的次数和响应时间及异常报警 项目中需要监控API接口的调用情况,如:调用次数,每次调用耗时,调用高峰期,异常报警等 grafana graphite stastd这一套对代码没有侵入,也不会影响接口性能 安装docker环…

【C语言】【牛客】BC136 KiKi判断上三角矩阵

文章目录 题目 BC136 KiKi判断上三角矩阵思路代码呈现 题目 BC136 KiKi判断上三角矩阵 链接: link 思路 这题很简单但是再牛客中属于中等题 我们通过读题发现 2<n<10 &#xff0c;所以我们首先创建一个变量 n 以及一个 10*10 个元素数组 然后题目是判断该矩阵是否是…

Fetch、Axios 和 jQuery(Ajax) 三种常用的网络请求技术

Fetch、Axios 和 jQuery(Ajax) 是三种常用的网络请求技术&#xff0c;它们各自有着不同的特点和优势。本文将对这三种技术进行详细的介绍和比较&#xff0c;以帮助开发者更好地选择和使用合适的网络请求技术。 一、Fetch Fetch(浏览器自带) 是一种现代的网络请求 API&#xff…

强大的文本编辑器:Sublime Text for Mac注册激活版

Sublime Text for Mac是一款功能强大的文本编辑器&#xff0c;特别适合程序员和开发者使用。它提供了丰富的功能&#xff0c;如智能代码补全、语法高亮、自定义快捷键、项目管理、多行选择、自动保存等&#xff0c;以提高代码编写效率和舒适度。此外&#xff0c;Sublime Text还…

SQLiteC/C++接口详细介绍sqlite3_stmt类(四)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;三&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;五&#xff09; 7. sqlite3_bind_parameter_count函数 sqlite3_bind_param…

数据库设计三大范式

第一范式 确保每列保持原子性 即数据库表中的所有字段值都是不可分解的原子值 如果地址这个字段频繁访问&#xff0c; 则将地址这个属性重新划分为 省份 城市&#xff0c;详细地址等部分进行存储&#xff0c;这样才算是满足数据库的第一范式 第二范式 确保表中的每列都和主…

SpringCloud中的@EnableDiscoceryClient和@EnableFeignClients注解的作用解析、RPC远程过程调用

目录 EnableDiscoveryClient 服务发现的核心概念 服务注册中心 EnableDiscoveryClient注解的作用 服务心跳健康检查 使用示例 EnableFeignClients Feign简介 EnableFeignClients注解的作用 RPC&#xff08;Remote Procedure Call&#xff09; 参考链接 Spring Cloud…

企业工商年报注册注销商标注册异常处理小程序开源版开发

企业工商年报注册注销商标注册异常处理小程序开源版开发 1、独立业务模型包括&#xff1a;企业工商年报、企业工商登记注册、企业注销登记、企业异常处理。 2、通用业务模型适合各种业务&#xff0c;比如&#xff1a;商标注册代理、财务会计服务、企业版权登记登。 当然&…

CAPL如何实现TCP Packet的option字段

在TCP协议中,主机可以根据自身的需要决定TCP通信时是否携带option字段,来扩展TCP功能。option字段属于TCP首部的扩展部分,且是可选项,TCP根据首部中的offset字段值确定TCP报文是否携带option字段。 TCP首部固定的部分有20个字节,如果没有扩展部分(option字段),20个字节…

《论文阅读》带边界调整的联合约束学习用于情感原因对提取 ACL 2023

《论文阅读》带边界调整的联合约束学习用于情感原因对提取 前言简介Clause EncoderJoint Constrained LearningBoundary Adjusting损失函数前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦~ 无抄袭,无复制,纯手工敲击键盘~ 今天为大家带来的是《Joint Cons…

图像分割论文阅读:Adaptive Context Selection for Polyp Segmentation

这篇论文的主要内容是关于一种用于息肉分割的自适应上下文选择网络&#xff08;Adaptive Context Selection Network&#xff0c;简称ACSNet&#xff09; 1&#xff0c;模型的整体结构 模型的整体结构基于编码器-解码器框架&#xff0c;并且包含了三个关键模块&#xff1a;局部…