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

 假设有个类的继承体系,用于建模股票交易,例如买入订单、卖出订单等。此类交易是可审计的,因此每次创建交易对象时,都需要在审计日志中创建适当的条目。

class Transaction { // 所有交易的基类
public: 
    Transaction();
    virtual void logTransaction() const = 0; // 创建依赖于类型的日志条目
    ...
};
Transaction::Transaction() // 基类构造函数的实现
{ 
    ...
    logTransaction(); // 最后,记录这笔交易
} 

class BuyTransaction : public Transaction { // 派生类
public:
    virtual void logTransaction() const; // 记录这种类型的交易
    ...
};
//考虑一下执行这段代码时会发生什么:
BuyTransaction b;

在这里插入图片描述

  • 派生类对象的基类部分在派生类部分之前构造。
  • 在构造基类时,虚函数永远不会进入派生类。
  • 在运行基类构造函数时,派生类数据成员没有初始化。
  • 而派生类函数几乎肯定会引用局部数据成员。
  • 在派生类构造函数开始执行之前,对象被视为基类对象。
  • 同样的道理也适用于析构函数。

 检测虚函数在构造或析构期间的调用并不总是那么容易。如果类有多个构造函数,每个构造函数都必须执行一些相同的工作,将它们放在私有的非虚拟初始化函数中,以避免代码复制:

class Transaction {
public:
    Transaction()
    {
        init();// 调用 non-virtual...
    } 
    virtual void logTransaction() const = 0;
    ...
private:
    void init()
    {
        ...
       logTransaction(); // ...这里调用virtual!
    }
};

在这里插入图片描述

解决这个问题有很多方法。一种是将logTransaction转换为非虚函数,然后要求派生类构造函数将必要的日志信息传递给基类构造函数。然后该函数可以安全地调用非虚的logTransaction:

class Transaction {
public:
    explicit Transaction(const std::string& logInfo);
    void logTransaction(const std::string& logInfo) const;//现在不是虚函数
    ...
};
Transaction::Transaction(const std::string& logInfo)
{
    ...
    logTransaction(logInfo); // 现在调用的不是虚函数
} 
class BuyTransaction : public Transaction {
public:
    BuyTransaction(parameters)
        : Transaction(createLogString(parameters)) // 将日志信息
							// 传递给基类构造函数
    {
        ...
    }     
    ... 
private:
    static std::string createLogString(parameters);
};

在这里插入图片描述

  • 由于不能再基类的构造函数中使用虚函数向下调用,可以通过让派生类将必要的构造信息向上传递给基类的构造函数来进行补偿。
  • 使用辅助函数来创建一个值并传递给基类的构造函数,通常比通过修改成员初始化列表来提供基类所需的值更方便(可读性也更好)。
  • 通过将函数设置为静态,就不会有意外引用BuyTransaction对象尚未初始化的数据成员的危险。
    不要在构造或析构过程中调用虚函数,因为这样的调用永远不会下降至派生的类(相对于正在执行的构造函数或析构函数的那一层)。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RIPEMD加密算法:原理、应用与安全性

一、引言 在信息时代,数据安全愈发受到重视,加密算法作为保障信息安全的关键技术,其性能和安全性备受关注。RIPEMD(RACE Integrity Primitives Evaluation Message Digest)加密算法作为一种著名的哈希函数&#xff0c…

Folium基础使用-python创建交互式地图与标记

使用 Folium 创建交互式地图与标记 Folium 是一个基于 Leaflet.js 的 Python 库,用于创建交互式地图。下面我们将分别介绍 folium.Map 和 folium.Marker 的使用,展示如何创建一个简单的地图并在上面添加标记点。 创建地图 - folium.Map 首先&#xff…

Stream流的简单使用

stream流的三类方法 获取Stream流 ○ 创建一条流水线,并把数据放到流水线上准备进行操作中间方法 ○ 流水线上的操作 ○ 一次操作完毕之后,还可以继续进行其他操作终结方法 ○ 一个Stream流只能有一个终结方法 ○ 是流水线上的最后一个操作 其实Stream流非常简单,只…

毕设之-消息系统设计(websocket+netty)

文章目录 前言技术选型基本架构 前言 long time no see。 前几天去一家小公司待了待,果断还是选择跑路,第三天就去另一家公司考察环境,和主管聊了两个多小时,非常愉快,就是单位薪资砍了一半。哎,旧事莫提了…

如何给linux内核的config增加新驱动选项?

Kconfig 在Kconfig中添加config选项,可以参考其他同级配置,CAN_F81601最终选中后,会传给Makefile为CONFIG_CAN_F81601,而tristate后面的则是在menuconfig中的文本提示,只要只管可以理解均可 config CAN_F81601trista…

摄影企业网站搭建的作用是什么

几乎每个成年人都有一部手机,在互联网信息时代,手机的作用不言而喻,拍照/摄像成为了不少人经常会做的事,拍一张美美的照片发到社交圈赢得赞声,或是为以后留下回忆或发给自己在意的人,但这只限于生活记叙类图…

玩转大数据21:基于FP-Growth算法的关联规则挖掘及实现

1.引言 关联规则挖掘是大数据领域中重要的数据分析任务之一,其可以帮助我们发现数据集中项目之间的关联关系。关联规则挖掘是指在交易数据或者其他数据集中,发现一些常见的关联项,如购物篮中经常一起出现的商品组合。关联规则挖掘的应用非常…

【FPGA 器件比较】Altera -- Xilinx

比较以下市场前二名的产品线及定位 应用场景XilinxAltera高性能VersalAgilex F/I性能Virtex / Kintex / Artix / Zynq UltraScaleAgilex F/I / Stratix 10中档Virtex / Kintex / Zynq ~ 7 / UltraScaleStratix 10 / Arria 10低成本Artix-7 Sparton-7Cyclone 10 如上表&#x…

【C++】STL 容器 - stack 堆栈容器 ① ( stack 堆栈容器特点 | stack 堆栈容器与 deque 双端数组容器对比 | 简单示例 )

文章目录 一、 stack 堆栈容器简介1、stack 堆栈容器引入2、stack 堆栈容器特点3、stack 堆栈容器与 deque 双端数组容器对比 二、 代码示例 - stack 堆栈容器简单示例1、代码示例2、执行结果 一、 stack 堆栈容器简介 1、stack 堆栈容器引入 C 语言中的 STL 标准模板库 中的 s…

【Java】springmvc

文章目录 SpringMVC1、SpringMVC简单入门2、请求与响应2.1、请求映射路径2.2、接收请求参数2.3、接收请求体2.4、Convertor接口2.5、接收时间日期2.6、响应数据 3、REST风格RESTful快速开发 4、异常处理器5、拦截器5.1、拦截器制作5.2、拦截器三个方法的参数5.3、拦截器链 Spri…

excel统计分析——S-W正态性检验

参考资料: [1]马兴华,张晋昕.数值变量正态性检验常用方法的对比[J].循证医学,2014,14(02):123-128. 统计推断——正态性检验(图形方法、偏度和峰度、统计(拟合优度)检验)_sm.distributions.ecdf-CSDN博客 【统计学】…

智能优化算法应用:基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于向量加权平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.向量加权平均算法4.实验参数设定…

LabVIEW与PID在温度测控系统中的应用

LabVIEW与PID在温度测控系统中的应用 本案例介绍LabVIEW在温度控制系统中的应用,特别是结合PID算法。项目使用abVIEW作为主要开发工具,配合NI PCI-7831R数据采集和控制设备,实现了高效的温度调节。 系统的核心在于LabVIEW的FPGA模块&#x…

基于JAVA的超市账单管理系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统设计3.1 总体设计3.2 前端设计3.3 后端设计在这里插入图片描述 四、系统展示五、核心代码5.1 查询供应商5.2 查询商品5.3 新增超市账单5.4 编辑超市账单5.5 查询超市账单 六、免责说明 一、摘要 1.1 项目介绍 基于…

游戏服务器列表-增量处理

前言:服务器列表比较简单 固定表/开服表(一般只会增加及合并),操作频率很低 一般由 服务器ID IP NAME 开服时间 状态表 服务器ID 状态 这章主要针对 开服表 优化处理 这工具主要是配置前面openresty(登录服/微中台)给运维人员 使用…

【Pytorch】学习记录分享7——PyTorch数据增强/经典网络架构训练图像分类模型

【Pytorch】学习记录分享7——PyTorch 1. 数据增强、transform 模块数据预处理部分:网络模块设置:网络模型保存与测试 2. 迁移学习3. 参考pytorch官网例子 1. 数据增强、transform 模块 数据预处理部分: 数据增强:torchvision中…

MOSFET管驱动设计细节,波形分析

MOSFET管驱动设计细节,波形分析 Chapter1 MOSFET管驱动设计细节,波形分析MOSFET驱动芯片的内部结构MOS驱动电路设计需要注意的地方MOS管驱动电路参考MOS管驱动电路的布线设计常见的MOS管驱动波形高频振铃严重的毁容方波又胖又圆的肥猪波打肿脸充正弦的生于方波他们家的三角波大…

性能篇:字符串性能优化不容小觑

嗨,大家好!我是小米,一个热衷于技术分享的小伙伴。今天,我们一起来聊一聊在Java中如何优化字符串性能,探讨一些令人激动的方法,让你的程序在处理字符串时更加高效! 为什么String设计为不可变性…

微机原理与接口技术——并行I/O接口(8255A)

文章目录 一、内部结构、端口地址以及与系统总线的连接1、8255A的内部结构2、8255A的端口地址与读/写操作端口地址读/写操作 3、系统总线 二、8255A三种工作方式(方式0 ~方式2 )的工作特点和I/O过程工作方式工作特点 三、在方式1中C口哪几个引脚作为信号…

Plantuml之时序图语法介绍(二十)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…