Effective C++ 条款19: 设计class犹如设计type

Effective C++ 条款19:设计class犹如设计type


核心思想设计新的class时,应当像语言设计者设计内置类型一样慎重,考虑对象的创建、销毁、初始化、拷贝、类型转换等所有方面。

⚠️ 1. 类设计的关键问题域

对象生命周期管理

class ResourceHandle {
public:// 构造和析构:资源如何获取?如何释放?ResourceHandle(const std::string& resId);~ResourceHandle();  // 需要释放资源吗?private:Resource* resource_;
};

值语义与行为

class Rational {
public:// 拷贝操作:允许拷贝吗?浅拷贝还是深拷贝?Rational(const Rational& other);Rational& operator=(const Rational& other);// 类型转换:支持隐式转换吗?operator double() const;  // 危险:可能非预期转换
};

🚨 2. 解决方案:系统化设计方法

明确对象创建方式

class Session {
public:// 静态工厂方法:控制创建逻辑static Session createFromNetwork();static Session createFromFile(const std::string& path);// 禁用拷贝Session(const Session&) = delete;Session& operator=(const Session&) = delete;
private:Session();  // 私有构造
};

安全类型转换接口

class SafeRational {
public:// 显式转换函数(C++11)explicit operator double() const { return static_cast<double>(numerator)/denominator; }// 转换运算符替代方案double toDouble() const { /* ... */ }  // 更安全的显式转换
};

⚖️ 3. 关键设计原则与决策
设计维度关键问题推荐实践
对象创建/销毁构造函数参数?析构函数必要性?RAII模式管理资源
初始化/赋值区别构造函数与赋值操作符行为是否一致?确保一致性
值传递方式pass-by-value是否高效?小对象传值,大对象传const引用
操作符重载哪些操作符需要重载?仅重载符合直觉的操作符
类型转换控制是否允许隐式转换?使用explicit禁止非预期转换
成员访问权限哪些成员公开?哪些需要保护?最小化public接口
继承体系设计是否作为基类?虚函数如何设计?明确声明finaloverride
模板泛化可能性是否应设计为类模板?评估未来需求
标准库兼容性是否满足STL容器要求?提供必要的类型特征

成员函数设计规范

class Polynomial {
public:// 常量成员函数:不修改对象状态double evaluate(double x) const noexcept;// 异常安全保证void normalize() &;  // 仅限左值对象调用// 引用限定符(C++11)void process() &&;   // 仅限右值对象调用
};

继承体系设计规范

// 接口类设计
class Drawable {
public:virtual void draw() const = 0;virtual ~Drawable() = default;// 禁止拷贝(接口类通常不可拷贝)Drawable(const Drawable&) = delete;Drawable& operator=(const Drawable&) = delete;
};// 具体实现类
class Circle final : public Drawable {
public:void draw() const override;  // 明确重写// ...                         // 禁止进一步继承(final)
};

💡 关键原则总结

  1. 生命周期全周期设计
    • 构造/析构:资源获取即初始化(RAII)
    • 拷贝控制:明确=default/=delete拷贝操作
  2. 类型行为一致性
    • 操作符重载:行为需符合内置类型预期
    • 类型转换:优先使用explicit和命名转换函数
  3. 接口最小化原则
    • 成员函数:提供完备但最小的操作集合
    • 访问控制:严格限制private/protected
  4. 继承体系明确性
    • 基类:声明虚析构函数,明确抽象接口
    • 派生类:使用final/override明确意图

危险类设计示例

class AutoPtr {  // 已废弃的auto_ptr问题
public:// 问题1:允许从临时对象构造AutoPtr(AutoPtr& other);  // 非const引用// 问题2:转移所有权但不明确AutoPtr& operator=(AutoPtr& other);// 问题3:支持隐式指针转换operator void*() const;  // 可能导致误用
};

安全重构方案

// 解决方案:现代unique_ptr设计理念
template<typename T>
class UniquePtr {
public:// 明确所有权转移语义UniquePtr(UniquePtr&& other) noexcept;  // 移动构造UniquePtr& operator=(UniquePtr&& other) noexcept; // 移动赋值// 禁止拷贝UniquePtr(const UniquePtr&) = delete;UniquePtr& operator=(const UniquePtr&) = delete;// 显式bool转换(安全)explicit operator bool() const noexcept;// 明确资源释放接口void reset() noexcept;T* release() noexcept;
};

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

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

相关文章

《汇编语言:基于X86处理器》第11章 MS-Windows编程(3)

本章展示的是如何用32 位Microsoft Windows API进行控制台窗口编程。应用编程接口(API:ApplicationProgramming Interface)是类型、常数和函数的集合体&#xff0c;它提供了一种用计算机代码操作对象的方式。本章将讨论文本I/O、颜色选择、时间与日期、数据文件I/O&#xff0c;…

在 macOS 上通过 Docker 部署DM8 (ARM 架构)

概述 达梦数据库 (DM8) 无法直接在 Apple macOS 操作系统上原生安装&#xff0c;通常需要通过虚拟机&#xff08;如 Parallels Desktop、VMware Fusion&#xff09;进行部署。另一种更轻量级且受 macOS 支持的方案是利用 Docker 容器技术来构建开发与测试环境。本文档将详细介…

网络协议之路由是怎么回事?

写在前面 要想去外面的世界看看, 就离不了路由器&#xff0c;而路由器工作的原理就是路由&#xff0c;那么具体是怎么路由的呢&#xff1f;本文就一起来看下这部分内容。 1&#xff1a;路由的配置 配置一条路由无非就是在配置以下三个信息&#xff1a; 1:包要去哪里&#x…

2106. 摘水果,梳理思路

文章目录题目概要java 解法详解题目概要 在一个无限的 x 坐标轴上&#xff0c;有许多水果分布在其中某些位置。给你一个二维整数数组 fruits &#xff0c;其中 fruits[i] [positioni, amounti] 表示共有 amounti 个水果放置在 positioni 上。fruits 已经按 positioni 升序排列…

深入理解消息队列(MQ)核心原理与设计精髓

引言&#xff1a;从一个“不堪重负”的订单系统说起想象一个简化的电商下单流程&#xff1a;用户点击“下单”后&#xff0c;系统需要&#xff1a;在订单数据库中创建一条记录。调用库存服务&#xff0c;扣减商品库存。调用营销服务&#xff0c;给用户发放积分和优惠券。调用通…

前端手撕题总结篇(算法篇——来自Leetcode牛客)

链表指定区域反转 找到区间&#xff08;头和为 for循环当**时&#xff09;->反转链表&#xff08;返回反转过后的头和尾&#xff09;->连接 function reverseBetween( head , m , n ) {//preEnd&cur&nextStart cur.next断开if(mn)return head;const vHeadNode…

从Excel到工时管理系统:企业如何选择更高效的工时记录工具?

还在为手工统计员工工时而头疼吗&#xff1f;月末堆积如山的Excel表格、反复核对的数据、层出不穷的差错&#xff0c;这些问题正在拖慢企业的发展步伐。8Manage工时管理系统发现&#xff0c;传统手工记录不仅耗费大量人力&#xff0c;更让宝贵的工时数据难以转化为有效的管理决…

Java设计模式之《命令模式》

目录 1、介绍 1.1、命令模式定义 1.2、对比 1.3、典型应用场景 2、命令模式的结构 2.1、组成部分&#xff1a; 2.2、整体流程 3、实现 3.1、没有命令模式 3.2、命令模式写法 4、命令模式的优缺点 前言 java设计模式分类&#xff1a; 1、介绍 1.1、命令模式定义 命…

【动态规划算法】路径问题

什么是动态规划算法动态规划&#xff08;Dynamic Programming&#xff0c;简称 DP&#xff09;是一种通过分解复杂问题为重叠子问题&#xff0c;并存储子问题的解以避免重复计算&#xff0c;从而高效求解具有特定性质&#xff08;重叠子问题、最优子结构&#xff09;问题的算法…

Java基本技术讲解

一、基础语法三要素 暂时无法在飞书文档外展示此内容 &#x1f511; 黄金法则​&#xff1a;每个变量都要声明类型&#xff01;二、程序逻辑控制&#xff08;游戏行为核心&#xff09; 条件判断&#xff1a;if-else - “岔路口选择” // 捡到金币逻辑 if (isTouching(Coin.clas…

【网络基础2】路由器的 “两扇门”:二层接口和三层接口到底有啥不一样?

目录 前言:路由器不是只有 “插网线的口” 一、先搞懂一个基础:路由器是 “网络交通枢纽” 二、二层接口:“小区内部的单元门”,只认 “住户身份证” 1. 啥是二层接口? 2. 用 “小区内部串门” 理解二层接口 步骤 1:手机打包数据,写上 “收件人身份证” 步骤 2:二…

MLIR TableGen

简介 TableGen 是一种领域特定语言&#xff08;DSL&#xff09;&#xff0c;TableGen 的设计目标是允许编写灵活的描述&#xff0c;并将记录的通用特性提取出来&#xff0c;从而减少重复代码并提高代码的可维护性。 TableGen的工作流程&#xff1a; 前端解析&#xff1a; Ta…

2、docker容器命令 | 信息查看

1、命令总览命令作用docker ps查看运行中的容器&#xff08;-a查看所有容器&#xff09;docker logs [CONTAINER]查看容器日志&#xff08;-f实时追踪日志&#xff09;docker inspect [CONTAINER]查看容器详细信息&#xff08;JSON格式&#xff09;docker stats [CONTAINER]实时…

【MySQL】MySQL中锁有哪些?

一、按照粒度分类&#xff1a; 粒度越小&#xff0c;并发度越高&#xff0c;锁开销越大。 1.全局锁&#xff1a; 作用&#xff1a; 锁定整个MySQL实例(所有数据库)。适用场景&#xff1a; 全库逻辑部分。(确保备份期间数据的一致性。)实现方式&#xff1a; 通过 FLUSH TABLES W…

语义分割--deeplabV3+

根据论文网络结构图讲一下&#xff1a;网络分为两部分&#xff1a;encoder和decoder部分。 Encoder&#xff1a;DCNN就是主干网络&#xff0c;例如resnet&#xff0c;Xception&#xff0c;MobileNet这些&#xff08;主干网络也要使用空洞卷积&#xff09;&#xff0c;对dcnn的结…

Azure DevOps 中的代理

必知词汇 深入研究 Azure DevOps 中的代理之前需要掌握的基本概念: 代理:Azure DevOps 中的代理是一个软件组件,负责执行流水线中的任务和作业。这可能包括数据中心内的物理服务器、本地或云端托管的虚拟机,甚至是容器化环境。这些代理可以在各种操作系统和环境中运行,例如…

AUTOSAR进阶图解==>AUTOSAR_SRS_ADCDriver

AUTOSAR ADC驱动详解 基于AUTOSAR标准的ADC驱动模块需求规范分析目录 ADC驱动模块概述 关键概念定义 ADC驱动架构 ADC驱动在AUTOSAR分层架构中的位置ADC驱动的主要职责 ADC驱动配置结构 通用配置(AdcGeneral)硬件单元配置(AdcHwUnit)通道配置(AdcChannel)通道组配置(AdcChanne…

宝马集团与SAP联合打造生产物流数字化新标杆

在德国雷根斯堡的宝马工厂&#xff0c;每57秒就有一辆新车下线。这座工厂不仅是汽车制造的基地&#xff0c;更是宝马集团向SAP S/4HANA云平台转型的先锋项目。通过“RISE with SAP”计划&#xff0c;宝马将该工厂的运营系统全面迁移至SAP S/4HANA Cloud Private Edition&#x…

Go 语言实战:构建一个高性能的 MySQL + Redis 应用

引言&#xff1a;为什么是 Go MySQL Redis&#xff1f;在现代后端技术栈中&#xff0c;Go MySQL Redis 的组合堪称“黄金搭档”&#xff0c;被广泛应用于各种高并发业务场景。Go 语言&#xff1a;以其卓越的并发性能、简洁的语法和高效的执行效率&#xff0c;成为构建高性能…

Excel超级处理器,多个word表格模板中内容提取到Excel表格中

在职场中&#xff0c;很多人习惯在word里插入表格&#xff0c;设计模板&#xff0c;填写内容&#xff0c;一旦有多个word文件需要整理在excel表格中&#xff0c;最常见的工作方式就是每个word文件打开&#xff0c;复制&#xff0c;粘贴到excel表格里&#xff0c;这样的工作方式…