c++_继承

🏷如被何实现一个不能被继承的类(或是继承无意义的类)

将构造函数定义成私有的就行了,即:私有化父类的构造函数
c++ 11 新增关键字final 修饰父类直接不能被继承

class A final
{........
}

🏷继承与有元

有元关系不能被继承


🏷继承与静态成员

思考一个问题?静态成员变量可以继承吗 ?
你会发现在子类中确实可以访问静态成员变量,但是当你打印父类的静态成员变量和子类的静态成员变量的时候你会发现他们的地址是一样的。
我们可以这样来理解:首先静态成员变量它不是属于某一个对象的,它是属于整个类的。所以它这里只是相当继承了使用权,其实这里的静态成员变量的继承和成员函数的继承很像,子类继承父类的成员函数也是继承的使用权,并不是自己在单独去创建一份。


🏷复杂的菱形继承及菱形虚拟继承

📌单继承:一个子类只有一个直接父类时称这个继承关系为单继承

![[Pasted image 20231121171709.png]]

📌多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承

📌菱形继承:菱形继承是多继承的一种特殊情况。

菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余二义性的问题
在这里插入图片描述

📌怎么分析的?

首先这个Assistant 继承了Student ,同时又继承了TeacherStudent 里面有成员变量:_age, _name, 等Teacher 里面也有成员变量:_age, _name, 等,当你想访问,Assistant时,就有两个_age 两个_name ,编译器不知道你想要的是哪个,所以就存在二义性
而且,就算你能容忍这个问题,但是所有的信息存两份会造成空间的白白浪费。

📌解决方法

为了解决菱形继承的上面两个问题,c++的祖师爷想出了一个新的办法,增加了一个新的关键字:virtual 虚继承

class Person
{
public:string _name; // 姓名
};
class Student : virtual public Person  //看在这里加上了 关键字:vitual
{
protected:int _num; //学号
};
class Teacher : virtual public Person
{
protected:int _id; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};

加上了vitual 之后,就是继承的同一份了,就避免了数据冗余的问题。

📌虚拟继承解决数据冗余和二义性的原理

一下面的代码为列:

#include<iostream>
using namespace std;class A
{
public:int _a;
};
// class B : public A
class B : virtual public A
{
public:int _b;
};
// class C : public A
class C : virtual public A
{
public:int _c;
};
class D : public B, public C
{
public:int _d;
};int main()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;return 0;
}
✒如何解决二义性的问题的?

我们可以通过指定类域的方法来避免这个二义性的问题:
b.B::_a = 1
b.C::_a = 2

✒如何解决数据冗余的问题的?

对象d 要存一个来自父类的成员变量_a 为了避免数据冗余,我们就不在B类和c类中存这个成员变量了,我们把_a 单独存一个地方,这样无论你使用b.B::_a = 1 还是b.c::_a = 2访问的都是一个地方,这样数据冗余的问题就解决了。

🏷继承的总结和反思

  1. 很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱

形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设

计出菱形继承。否则在复杂度及性能上都有问题。

  1. 多继承可以认为是C++的缺陷之一,很多后来的OO语言都没有多继承,如Java。

🏷继承和组合

📌什么是组合?

class C
{int _c;
};class D
{
protected:C _c;
};

上面的代码例子就是组合。
想一想:继承和组合的相同点是什么,不同点是什么?
🔎相同点:
1. 都可以复用(继承的核心是复用:子类复用父类

🔎不同点:

#include<iostream>
using namespace std;//继承
class A
{
public:void func(){}
protected:int _a;};class B: public A
{
public:void f(){           //继承的权限是比较大的除了父类的私有不可见其他的都是可以使用的func(); //父类的公有可以用_a++;     //父类的保护也可以用}
protected:	int _b;
};//组合
class C
{
public:void func(){}
protected:int _c;
};class D
{
public:void f(){_c.func(); //组合类的公有可以使用//_c._a++;   //但是组合类的保护不能使用}
protected:C _c;int _d;
};int main()
{cout << sizeof(D) << endl;cout << sizeof(B) << endl;D dd;dd.func(); //组合类的d对象不能直接调用func;B bb;bb.func(); //继承的子类B对象就能直接调用父类的func();}

优先使用对象组合,而不是类继承 。

继承允许你根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称

为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,基类的

内部细节对子类可见 。继承一定程度破坏了基类的封装,基类的改变,对派生类有很

大的影响。派生类和基类间的依赖关系很强,耦合度高。

对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象

来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复

用(black-box reuse),因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。

组合类之间没有很强的依赖关系,耦合度低。优先使用对象组合有助于你保持每个类被

封装。

实际尽量多去用组合。组合的耦合度低,代码维护性好。不过继承也有用武之地的,有
些关系就适合继承那就用继承,另外要实现多态,也必须要继承。类之间的关系可以用
继承,可以用组合,就用组合

📌什么时候用组合,什么时候用继承

public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。

组合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象。

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

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

相关文章

【Python进阶笔记】md文档笔记第6篇:Python进程和多线程使用(图文和代码)

本文从14大模块展示了python高级用的应用。分别有Linux命令&#xff0c;多任务编程、网络编程、Http协议和静态Web编程、htmlcss、JavaScript、jQuery、MySql数据库的各种用法、python的闭包和装饰器、mini-web框架、正则表达式等相关文章的详细讲述。 全套md格式笔记和代码自…

还不会配置Nginx?刷完这篇就够了

Nginx是一个开源的高性能HTTP和反向代理服务器。它可以用于处理静态资源、负载均衡、反向代理和缓存等任务。Nginx被广泛用于构建高可用性、高性能的Web应用程序和网站。它具有低内存消耗、高并发能力和良好的稳定性&#xff0c;因此在互联网领域非常受欢迎。 为什么使用Nginx…

【vue_2】创建一个弹出权限不足的提示框

定义了一个名为 getUserRole 的 JavaScript 函数&#xff0c;该函数接受一个参数 authorityId&#xff0c;根据这个参数的不同值返回相应的用户角色字符串。这段代码的目的是根据传入的 authorityId 值判断用户的角色&#xff0c;然后返回相应的角色名称。 如果 authorityId 的…

【源码】智慧工地系统:让工地管理可视化、数字化、智能化

智慧工地是指运用信息化手段&#xff0c;围绕施工过程管理&#xff0c;建立互联协同、智能生产、科学管理的施工项目信息化生态圈&#xff0c;并将此数据在虚拟现实环境下与物联网采集到的工程信息进行数据挖掘分析&#xff0c;提供过程趋势预测及专家预案&#xff0c;实现工程…

切换服务器上自己用户目录下的 conda 环境和一个外部的 Conda 环境

如果我们有自己的 Miniconda 安装和一个外部的 Conda 环境&#xff08;比如一个全局安装的 Anaconda&#xff09;&#xff0c;我们可以通过修改 shell 环境来切换使用它们。这通常涉及到更改 PATH 环境变量&#xff0c;以便指向你想要使用的 Conda 安装的可执行文件&#xff1a…

分布式链路追踪实战篇-日志库集成opentelemetry的思路

由上文分布式链路追踪入门篇-基础原理与快速应用可以知道分布式链路追踪的作用&#xff0c;但是距离应用到项目中&#xff0c;我们还需要对项目中一些关键组件进行opentelemetry的集成&#xff0c;例如日志库&#xff0c;ORM、http框架、rpc框架等。 一、日志库如何集成opentel…

【最新版】SolidWorks 2023 SP5.0 完整版安装包+安装教程

分享模式&#xff1a;免费/绿色&#xff0c;按教程安装 下载地址&#xff1a; https://pan.xunlei.com/s/VNL0-DD_ogcRFwy-xi0HUtlyA1?pwdfzqw# 提取码&#xff1a;fzqw SOLIDWORKS 2023新版本对电脑配置要求 更多详细说明请去官网查看。 安装使用方法&#xff1a; 一、卸…

Windows下安装MySQL

几年前学习mycat中间件的时候在window机器上安装过MySql&#xff0c;但是由于电脑配置不高&#xff0c;同时打开Mysql服务&#xff0c;idea、SQlyog等软件非常卡&#xff0c;再加上SQLyog和MySQL版本不兼容导致登录不上&#xff0c;于是把它卸载了。最近做练习需要&#xff0c;…

IBM X3650M4安装ESXI6.5卡在/lsl_mr3.v00

环境&#xff1a;IBM X3650M4服务器双盘配置raid1&#xff0c;通过rufus制作启动U盘&#xff0c;安装VMware Vsphere 5.5系统 问题&#xff1a;卡在/lsi_mr3.v00界面无法往下运行&#xff08;两台配置一样的机器遇到同样的问题&#xff09; 解决方案&#xff1a; 直接在U盘根…

Python中如何选择Web开发框架?

Python开发中Web框架可谓是百花齐放&#xff0c;各式各样的web框架层出不穷&#xff0c;那么对于需要进行Python开发的我们来说&#xff0c;如何选择web框架也就变成了一门学问了。本篇文章主要是介绍目前一些比较有特点受欢迎的Web框架&#xff0c;我们可以根据各个Web框架的特…

计算机组成原理-固态硬盘SSD

文章目录 总览机械硬盘vs固态硬盘固态硬盘的结构固态硬盘与机械硬盘相比的特点磨损均衡技术例题 总览 机械硬盘vs固态硬盘 固态硬盘采用闪存技术&#xff0c;是电可擦除ROM 下图右边黑色的块块就是一块一块的闪存芯片 固态硬盘的结构 块大小16KB~512KB 页大小512B~4KB 对固…

【Java】智慧工地云平台源码(APP+SaaS模式)

在谈论“智慧工地”之前&#xff0c;我们首先得知道传统工地为什么跟不上时代了。 说起传统工地&#xff0c;总有一些很突出的问题&#xff1a;比如工友多且杂&#xff0c;他们是否入场、身体状况如何&#xff0c;管理人员只能依靠巡查、手工纪录来判断&#xff0c;耗时耗力&am…

FANUC机器人系统配置相关--系统变量介绍

FANUC机器人系统配置相关–系统变量介绍 系统配置页相关变量 1- 停电处理$SEMIPOWERFL = TRUE(有效)/FALSE(无效) 2- 停电处理中的I/O $PWF_IO = 1(不恢复)/2(仿真恢复)/3(解除仿真)/4(恢复所有) 3- 停电处理无效时自动执行的程序 $PWR_NORMAL = ‘’ 4- 停电处理有效时自动…

【vue_1】console.log没有反应

1、打印不出来&#xff1f;2、警告也会出现问题3、插播&#xff1a;如何使用if-else 语句来处理逻辑 1、打印不出来&#xff1f; 要做一个权限不够的弹出消息框 const authority_message () > {ElMessage({type: warrnings,message: 当前用户的权限不够});console.log(he…

Springboot学生疫情管理系统-计算机毕设 附源码 25567

Springboot学生疫情管理系统的设计与实现 摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出去&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤&#xf…

基于opencv+ImageAI+tensorflow的智能动漫人物识别系统——深度学习算法应用(含python、JS、模型源码)+数据集(二)

目录 前言总体设计系统整体结构图系统流程图 运行环境爬虫模型训练实际应用 模块实现1. 数据准备1&#xff09;爬虫下载原始图片2&#xff09;手动筛选图片 相关其它博客工程源代码下载其它资料下载 前言 本项目通过爬虫技术获取图片&#xff0c;利用OpenCV库对图像进行处理&a…

为何百兆静态库能打进数兆的可执行文件?

第三方库是工程开发必不可少的部分&#xff0c;而第三方库可以是.a和.framework的静态库&#xff0c;也可以是.framework的动态库&#xff0c;其中静态库是最常用的方式。 静态库往往比较大&#xff0c;可在打包到可执行文件之后&#xff0c;对安装包大小的增加远远小于静态库本…

原生小程序图表

原生小程序使用图表 话不多说直接进入正题 官方文档: https://www.ucharts.cn/v2/#/ 下载文件 首先去gitee上把文件下载到自己的项目中 https://gitee.com/uCharts/uCharts 找到微信小程序和里面的组件 把里面src下的文件全部下载下来放入自己项目中 项目文件 新建文件…

SpringBoot——定制错误页面及原理

优质博文&#xff1a;IT-BLOG-CN 一、SpringBoot 默认的错误处理机制 【1】浏览器返回的默认错误页面如下&#xff1a; ☞ 浏览器发送请求的请求头信息如下&#xff1a; text/html会在后面的源码分析中说到。 【2】如果是其他客户端&#xff0c;默认则响应错误的 JSON字符串&…

git提交报错error: failed to push some refs to ‘git url‘

1.产生错误原因 想把本地仓库提交到远程仓库&#xff0c;报错信息如下 git提交报错信息 error: src refspec master does not match any error: failed to push some refs to git url 错误原因&#xff1a; 我们在创建仓库的时候&#xff0c;都会勾选“使用Reamdme文件初始化…