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.mzph.cn/news/758671.shtml

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

相关文章

算法笔记p251队列循环队列

目录 队列循环队列循环队列的定义初始化判空判满入队出队获取队列内元素的个数取队首元素取队尾元素 队列 队列是一种先进先出的数据结构&#xff0c;总是从队尾加入元素&#xff0c;从队首移除元素&#xff0c;满足先进先出的原则。队列的常用操作包括获取队列内元素的个数&a…

【Godot4.2】颜色完全使用手册

概述 本篇简单汇总Godot中的颜色的构造和使用&#xff0c;内容包括了&#xff1a; RGB、RGBA&#xff0c;HSV以及HTML16进制颜色值、颜色常量等形式构造颜色颜色的运算以及取反、插值用类型化数组、紧缩数组或PNG图片形式存储多个颜色 构造颜色 因为颜色是一种视觉元素&…

Jmeter接口测试步骤

一、使用工具测试 1、使用Jmeter对接口测试 首先我们说一下为什么用Posman测试后我们还要用Jmeter做接口测试&#xff0c;在用posman测试时候会发现的是一个接口一个接口的测试&#xff0c;我们每次测试成功后的数据&#xff0c;在工具中是无法保存的&#xff0c;再次测试的时…

【蓝桥杯入门记录】继电器、蜂鸣器及原理图分析

一、继电器、继电器概述 &#xff08;1&#xff09;蜂鸣器原理 蜂鸣器的发声原理由振动装置和谐振装置组成&#xff0c;而蜂鸣器又分为无源他激型与有源自激型&#xff0c;蜂鸣器的发声原理为: 1、无源他激型蜂鸣器的工作发声原理是&#xff1a;方波信号输入谐振装置转换为声…

Vue.js开发基础

单文件组件 使用Vite创建Vue项目后&#xff0c;目录结构中包含一些扩展名为.vue的文件&#xff0c;每个.vue文件都可用来定义一个单文件组件。Vue中的单文件组件是Vue组件的文件格式。每个单文件组件由模板、样式和逻辑3个部分构成。 运行结果&#xff1a; 1.模板 模板用于搭建…

PyTorch 深度学习(GPT 重译)(一)

第一部分&#xff1a;PyTorch 核心 欢迎来到本书的第一部分。在这里&#xff0c;我们将与 PyTorch 迈出第一步&#xff0c;获得理解其结构和解决 PyTorch 项目机制所需的基本技能。 在第一章中&#xff0c;我们将首次接触 PyTorch&#xff0c;了解它是什么&#xff0c;解决了…

爬虫基础:HTTP基本原理

爬虫基础&#xff1a;HTTP基本原理 前言HTTP基本原理URI 和 URLHTTP 和 HTTPSHTTP 请求过程请求与响应HTTP请求HTTP响应请求与响应的交互过程 HTTP 2.0二进制传输多路复用Header压缩服务器端提前响应内容安全 前言 了解 HTTP的基本原理&#xff0c;了解从往测览器中输人 URL到获…

算法沉淀——贪心算法四(leetcode真题剖析)

算法沉淀——贪心算法四 01.最长回文串02.增减字符串匹配03.分发饼干04.最优除法 01.最长回文串 题目链接&#xff1a;https://leetcode.cn/problems/longest-palindrome/ 给定一个包含大写字母和小写字母的字符串 s &#xff0c;返回 通过这些字母构造成的 最长的回文串 。 …

YOLOV5 改进:修改网络结构--C2f 模块

1、前言 YOLOV5 采用C3模块,类似于残差结构的思想 class C3(nn.Module):# CSP Bottleneck with 3 convolutionsdef __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansionsuper().__init__()c_ = int(c2 * e) #…

Linux中,运行程序,顺便将打印信息存储在Log文件中查看

前言 如题&#xff0c;原本打算在代码中自己写一个类去管理将打印信息收集到log日志中&#xff0c;忽然想到&#xff0c;其实也可以写sh脚本 简单demo1 #!/bin/bash# 启动应用程序 test&#xff0c;并将标准输出和标准错误输出都追加到 log 文件中 ./test >> output.log…

7-7 12-24小时制

题目链接&#xff1a;7-7 12-24小时制 一. 题目 1. 题目 2. 输入输出格式 3. 输入输出样例 4. 限制 二、代码 1. 代码实现 #include <stdio.h>int main(void) {int hour, minute;char *str;if (scanf("%d:%d", &hour, &minute) ! 2) {return -1;}i…

操作系统系列学习——死锁处理

文章目录 前言死锁处理 前言 一个本硕双非的小菜鸡&#xff0c;备战24年秋招&#xff0c;计划学习操作系统并完成6.0S81&#xff0c;加油&#xff01; 本文总结自B站【哈工大】操作系统 李治军&#xff08;全32讲&#xff09; 老师课程讲的非常好&#xff0c;感谢 【哈工大】操…

如何优惠申请DigiCert证书

DigiCert作为全球知名的数字证书颁发机构&#xff0c;其SSL证书以高度的安全性和信任度广受认可。而JoySSL作为国内优秀的SSL证书服务平台&#xff0c;提供了便捷、高效的证书申请服务&#xff0c;让您能够轻松获取并安装DigiCert SSL证书。接下来&#xff0c;本文将详细介绍如…

什么情况用@RequestBody、@RequestParm、@PathVariable

1.requestParam(请求参数&#xff09;&#xff1a;使用RequestParam注释将请求参数绑定到控制器中的方法参数。用于从请求访问查询参数值的RequestParam注释。 如下请求URL&#xff1a;http://localhost:8080/springmvc/hello/101?param110&param220 以下是RequestParam注…

腾讯云服务器怎么买省钱?先领券,再下单!

腾讯云代金券领取渠道有哪些&#xff1f;腾讯云官网可以领取、官方媒体账号可以领取代金券、完成任务可以领取代金券&#xff0c;大家也可以在腾讯云百科蹲守代金券&#xff0c;因为腾讯云代金券领取渠道比较分散&#xff0c;腾讯云百科txybk.com专注汇总优惠代金券领取页面&am…

网工内推 | 七险一金,上市公司招信息安全工程师,大牛带队

01 启明星辰信息技术集团股份有限公司 招聘岗位&#xff1a;数据安全服务工程师 职责描述&#xff1a; 1、负责数据安全服务项目的管理&#xff0c;统筹组织并协调资源落实项目交付实施; 3、负责数据安全风险评估、数据分类分级、数据安全管理制度、数据安全体系规划等数据安…

企事业单位宣传,三下乡的稿子怎么在学习强国网投稿发稿,价格多少钱?

随着学习强国成为各个企事业单位宣传的重要平台&#xff0c;如何在学习强国上发稿&#xff0c;尤其是三下乡的宣传稿件&#xff0c;成为了各位传媒工作者关注的焦点。在这里&#xff0c;我们要向大家介绍一下媒介多多网发稿平台&#xff0c;为大家提供一个便捷高效的投稿发稿渠…

STM32相关资料汇总

STM32选型表 STM32手册参考网站 https://www.stmcu.org.cn/

命名空间——初识c++

. 个人主页&#xff1a;晓风飞 专栏&#xff1a;数据结构|Linux|C语言 路漫漫其修远兮&#xff0c;吾将上下而求索 文章目录 经典的Hello Word 起航c关键字c语言的命名冲突问题域作用限定符::命名空间 namespace命名空间定义命名空间的使用1.加命名空间名称及作用域限定符2.使用…

【CNN轻量化】ParameterNet: Parameters Are All You Need 参数就是你所需要的

论文链接&#xff1a;http://arxiv.org/abs/2306.14525 代码链接&#xff1a;https://github.com/huawei-noah/Efficient-AI-Backbones 一、摘要 现有的低FLOPs模型&#xff08;轻量化模型&#xff09;无法从大规模预训练中受益。本文旨在增加大规模视觉预训练模型中的参数数量…