当前位置: 首页 > news >正文

Effective C++看书笔记(2):构造/析构/赋值运算

构造/析构/赋值运算

  • 5:了解C++默默编写并调用哪些函数
  • 6:如果不想使用编译器自动生成的函数,就该明确拒绝
  • 7:为多态基类声明virtual析构函数
  • 8:别让异常逃离析构函数
  • 9:绝不在构造和析构过程中调用virtual函数
  • 10:令operator= 返回一个reference to *this
  • 11:在operator= 中处理自我赋值
  • 12:复制对象时勿忘其每一个成分

5:了解C++默默编写并调用哪些函数

如果我们没有任何声明,那么编译器就会默认生成一个copy构造函数,copy assignment操作符和一个析构函数以及一个默认构造函数。

所有这些函数都是Public以及inline的。

e2=e1;
A a;//默认构造函数。自己声明了,编译器就不生成了A(const A &a){}//这是copy构造函数,默认是把每个非静态成员拷贝过来,如果成员也是一个类型,那么会继续调用copy构造函数
A& operator=(const A& a){}//copy assignment操作符,默认同上

编译器生成的析构函数是non-virtual,除非这个类的基类声明是virtual。

6:如果不想使用编译器自动生成的函数,就该明确拒绝

编译器产出的函数都是Public

解决办法:把不想生成的函数,自己来定义,声明为private,代表不使用。

C++ iostream经常这样做。

但是这样member函数和friend函数还是可以使用。

解决办法:只声明函数,但不定义函数,调用的时候就会发现连接错误。

进一步解决就是把连接期错误转移到编译器。

解决办法是:专门写一个阻止copy动作的基类。基类只需要把copy之类的你不想生成的给设置为private。然后private继承基类即可。

7:为多态基类声明virtual析构函数

基类指针指向子类对象,如果基类的析构函数是non-virtual,那么会导致析构时只析构了基类的部分,但是没有析构掉子类的部分。

Base *pointer=&son;
delete pointer;

解决办法就是基类析构函数应该为virtual。(这只适用于多态性质,有些时候继承不是为了多态,就不要设置虚析构函数)

不要继承析构函数不是virtual的类

任何class只要带有virtual函数都几乎确定应该也有一个virtual析构函数。

如果class不含virtual函数,通常表示它并不意图被用做一个base class。当class不企图被当作base class,令其析构函数为virtual往往是个馊主意。

虚函数实现细节

要实现virtual函数,对象必须携带某些信息,主要用来在运行期决定哪一个virtual函数该被调用。

这份信息由vptr(virtual table pointer)指针指出。vptr指向一个由函数指针构成的数组,称为vtbl(virtual table);每一个带有virtual函数的class都有一个相应的vbtl。

当对象调用某一virtual函数,实际被调用的函数取决于该对象vptr所指的那个vtbl——编译器在其中寻找适当的函数指针。

纯虚函数(P43没看懂讲的啥)

class带一个纯虚函数会导致抽象类,即不能被实体化。

纯虚函数

virtual ~AWOV()=0;

析构函数调用顺序

从派生类开始依次向上。

8:别让异常逃离析构函数

C++不喜欢析构函数吐异常,就算吐,也要立刻解决。

例子:数据库关闭连接

~DBConn()
{db.close();
}

这样产生了异常,就很糟糕,没关闭成功还退出析构函数了,后续程序运行可能出行不好检查的bug

解决办法1:强制结束程序

DBConn::~DBConn()
{try{db.close();}catch(...){std::abort();}
}

解决办法2:强制结束程序

DBConn::~DBConn()
{try{db.close();}catch(...){//制作运行记录,记下close的失败。}
}

9:绝不在构造和析构过程中调用virtual函数

例子:

class Transaction{Transaction();virtual void logTransaction() const=0;
}
Transaction::Transaction()
{...logTransaction();
}class ButTransaction:public Transaction{public:virtual void logTransaction() const; 
}

下面这句代码有问题

ButTransaction b;

首先是ButTransaction构造函数调用,但是肯定Transaction构造函数会被更早调用(基类先构造完,才到子类)。

问题:Transaction构造函数最后一行调用了logTransaction,这个时候调用的是Transaction的版本,而不是ButTransaction的版本。

析构函数也同理。

10:令operator= 返回一个reference to *this

返回引用才能真正修改到值嘛

int a;
a=10;

11:在operator= 中处理自我赋值

没太看懂,记下结论

  • 确定任何函数如果操作一个以上的对象,而其中多个对象是同一个对象时,其行为仍然正确
  • 确保当对象自我赋值时operator=有良好行为。其中技术包括比较来源对象和目标对象的地址,精心周到的语句顺序,以及copy-and-swap。

12:复制对象时勿忘其每一个成分

一般只留两个函数负责对象拷贝(复制),即copy构造函数(A a(&A b))以及copy assignment(即=符号)。这些就是拷贝函数。

如果我们自己写了这些函数,不让编译器自动生成,那么新增成员变量一定要注意,还有就是注意拷贝完基类的所有部分

不该用copy assignment操作符调用copy构造函数。反过来也一样。重复代码用private函数init提取出来。

相关文章:

Effective C++看书笔记(2):构造/析构/赋值运算

构造/析构/赋值运算 5:了解C默默编写并调用哪些函数6:如果不想使用编译器自动生成的函数,就该明确拒绝7:为多态基类声明virtual析构函数8:别让异常逃离析构函数9:绝不在构造和析构过程中调用virtual函数10&…...

交换奇偶位:交换一个整数的二进制的奇偶位置(仅考虑正数情况)

方法二: 设计思想: 0xAAAAAAAA 的二进制表示为 10101010...(从最低位开始) 0x55555555 的二进制表示为 01010101...(从最低位开始) 问题:更加想不到掩码!!&#xf…...

Unity中的两种ScriptingBackend

一:前言 二:两种模式的介绍 ios:unity只有il2cpp模式的编译才支持64位系统,mono是不支持的,在快速开发阶段仍然支持Mono,但是不能再向Apple提交Mono(32位)的应用 苹果在2016年1月就要求所有新上架游戏必须支…...

vue3硅谷甄选01 | 使用vite创建vue3项目及项目的配置 环境准备 ESLint配置 prettier配置 husky配置 项目集成

文章目录 使用vite创建vue3项目及项目的配置1.环境准备2.项目配置ESLint校验代码工具配置 - js代码检测工具1.安装ESLint到开发环境 devDependencies2.生成配置文件:.eslint.cjs**3.安装vue3环境代码校验插件**4. 修改.eslintrc.cjs配置文件5.生成ESLint忽略文件6.在package.js…...

蓝牙核心规范(V5.4)10.5-BLE 入门笔记之HCI

HCI全称:HOST Constroller Interface 主机控制器接口(HCI)定义了一个标准化的接口,通过该接口,主机可以向控制器发出命令,并且控制器可以与主机进行通信。规范被分成几个部分,第一部分仅从功能的角度定义接口,不考虑具体的实现机制,而其他部分定义了在使用四种可能的…...

【计算机毕业设计】基于SpringBoot+Vue记帐理财系统的设计与实现

博主主页:一季春秋博主简介:专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发,远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容:毕业设计(Java项目、小程序、安卓等)、简历模板、学习资料、…...

2023年中国研究生数学建模竞赛E题

出血性脑卒中临床智能诊疗建模 一、背景介绍 出血性脑卒中指非外伤性脑实质内血管破裂引起的脑出血,占全部脑卒中发病率的10-15%。其病因复杂,通常因脑动脉瘤破裂、脑动脉异常等因素,导致血液从破裂的血管涌入脑组织,从而造成脑部…...

基于springboot+vue的大学生科创项目在线管理系统

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...

什么是文档签名证书?PDF文档怎么签名?

什么是文档签名证书?在“互联网”时代,电子合同、电子证照、电子病历、电子保单等各类电子文档无纸化应用成为常态。如何让电子文档的签署、审批具有公信力及法律效力,防止伪造签名、假冒签名等问题出现,是电子文档无纸化应用的主…...

2023年汉字小达人区级比赛倒计时2天,最新问题解答和真题练一练

今天是9月23日,距离2023年第十届汉字小达人区级比赛(初赛)的自由报名参赛时间还有2天,六分成长结合家长和小朋友们问的比较多的问题进行解答,并提供一些真题供大家练习、了解比赛题型和规则。 问题1:2023年…...

关于地址存放的例题

unsigned int a 0x1234; unsigned char b *(unsigned char*)&a; 上面代码大端存储和小端存储的值分别是多少? 大端存储的是把高位地址存放在低位地址处,低位存放到高位。小端是高位存放在高位,低位在低位。因为a是整型,所…...

Flume最简单使用

文章目录 一、简介1、定义2、基础架构 二、快速入门1、解压Flume2、案例一:监控端口号3、案例二:将空目录下文件 三、Flume进阶1、Flume事务2、Flume Agent内部原理3、案例一:监控日志4、案例二:多路复用和拦截器适应4.1 原理4.2 …...

第2章 Java集合

2.1 谈谈你对Java集合的理解 难度:★★★ 重点:★★★★ 白话解析 集合类的概念还是比较重要的,不仅面试经常问,实际开发中也离不开。如果能把这道题真正理解了,集合可以说基本上没问题了。 集合就用来用存数据的,它提供了对数据增删改查和统计大小等方法。在Java中集合…...

YOLOv5、YOLOv8改进:C3STR(Swin Transformer)

目录 1.介绍 2. YOLOv5、YOLOv8改进 2.1 common.py配置 2.2 yolo.py配置 2.3 yaml配置文件 1.介绍 视觉领域正在见证从 CNN 到 Transformers 的建模转变,纯 Transformer 架构在主要视频识别基准测试中达到了最高准确度。这些视频模型都建立在 Transformer 层之…...

AIGC百模大战

AIGC Artificial Intelligence Generated Content, 或者Generative Artificial Intelligence,它能够生成新的数据、图像、语音、视频、音乐等内容,从而扩展人工智能系统的应用范围。 生成式人工智能有可能给全球经济带来彻底的变化。根据高盛…...

docker jira 一键安装含PJ(docker 一键安装jira)

docker jira 一键安装含PJ(docker 一键安装jira) 本文仅供参考学习,请勿用于商业用途本文用于Jira在Docker的安装,仅用于记录安装方式转载请注明来源Linux安装可参考链接Windows安装可查考链接Docker一键安装Confluence PJ条件允…...

认识一下Git

目录 Git Git下载 Git安装 Git初始化 Git操作 Git、GitLab、和Eclipse是公司中软件开发常用的组合: 1. Git:Git是一种分布式版本控制系统,用于跟踪文件和代码的变化。它提供了管理代码仓库的功能,可以记录每次提交的修改&am…...

只需4步使用Redis缓存优化Node.js应用

介绍 通过API获取数据时,会向服务器发出网络请求,收到响应数据。但是,此过程可能非常耗时,并且可能会导致程序响应时间变慢。 我们使用缓存来解决这个问题,客户端程序首先向API发送请求,将返回的数据存储…...

【react基础01】项目文件结构描述

react 项目文件结构描述 📂 REACTWORKSPACE📂 node_modules📂 public📄 favicon.ico📄 index.html📄 logo192.png📄 logo512.png📄 manifest.json📄 robots.txt &#x1…...

光电开关-NPN-PNP

基础概念 有信号 “检测到物体/有物体遮挡” 工作原理 NPN:表示共正电压,输出负电压【只能输出低电压或者悬空 常开常闭是指 输出有没有跟“地”接通】; NPN NO:表示常态下是常开的,检测到物体时黑色线输出一个负电压…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...

网络编程(UDP编程)

思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...