Effective C++ 条款18:让接口容易被正确使用,不易被误用


核心思想设计接口时,应使正确使用方式直观自然,同时通过类型系统、行为约束等手段主动预防常见错误,减少用户犯错的可能性。

⚠️ 1. 接口误用的常见陷阱

日期类典型错误

class Date {
public:Date(int month, int day, int year);  // 原始接口// ...
};// 易错调用:参数顺序混乱
Date d(30, 3, 2023);  // 应该是(3,30,2023) → 月份30无效

资源管理陷阱

// 返回裸指针:谁负责释放?
Investment* createInvestment(); // 可能忘记释放 → 内存泄漏
// 或重复释放 → 程序崩溃

🚨 2. 解决方案:防御性接口设计

类型安全包装(Type-Safe Wrapping)

// 封装年月日为独立类型
struct Month {explicit Month(int m) : val(m) {}int val;
};
struct Day { /* 类似实现 */ };
struct Year { /* 类似实现 */ };class Date {
public:Date(const Month& m, const Day& d, const Year& y); // 安全接口
};Date d(Month(3), Day(30), Year(2023));  // 正确调用
Date d2(Day(30), Month(3), Year(2023)); // 编译错误!类型不匹配

智能指针自动管理

// 返回智能指针:明确所有权
std::shared_ptr<Investment> createInvestment();// 自动释放资源
// 可附加自定义删除器

⚖️ 3. 关键设计原则与技巧
设计原则实现技巧效果
强类型封装包装原始类型为域特定类型防止参数顺序错误
限制有效值范围使用枚举/静态检查避免非法参数输入
保持接口一致性遵循标准库命名/行为惯例降低学习成本
资源所有权明确化返回智能指针而非裸指针防止资源泄漏
行为兼容内置类型自定义类型支持与内置类型相同的操作符合用户直觉

值范围限制技巧

class Month {
public:static Month Jan() { return Month(1); }  // 工厂函数static Month Feb() { return Month(2); }// ...其余月份
private:explicit Month(int m);  // 私有构造
};// 使用示例:
Date d(Month::Mar(), Day(30), Year(2023));  // 安全构造

自定义删除器集成

// 自定义资源释放函数
void releaseInvestment(Investment* p); // 返回带自定义删除器的智能指针
std::shared_ptr<Investment> createInvestment() {return std::shared_ptr<Investment>(new Investment(), releaseInvestment  // 绑定删除器);
}

💡 关键原则总结

  1. 类型安全优先
    • Month/Day等域类型代替原始int
    • 禁用隐式类型转换(explicit构造函数)
  2. 接口自解释性
    • 参数名称/类型传达使用意图
    • 限制参数有效范围(如月份1-12)
  3. 所有权透明化
    • 工厂函数返回智能指针而非裸指针
    • 使用shared_ptr/unique_ptr明确资源归属
  4. 行为一致性
    • 自定义类型支持+/-等运算符
    • 容器接口与STL保持一致

错误接口设计重现

// 问题接口:原始指针+模糊参数
void* openFile(const char* name, int mode);// 典型误用:
File* f = (File*)openFile("data", 'r');  // 错误1:类型不安全// 错误2:模式参数错误

安全重构方案

// 解决方案1:强类型封装
class FileHandle {
public:enum OpenMode { Read, Write, Append };explicit FileHandle(const std::string& name, OpenMode mode = Read);~FileHandle();  // 自动关闭文件// ...
};// 解决方案2:工厂函数+智能指针
std::unique_ptr<FileHandle> openFile(const std::string& name,FileHandle::OpenMode mode = FileHandle::Read
);// 使用示例:
auto file = openFile("data.txt", FileHandle::Read);

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

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

相关文章

nodejs读写文件

1.读文件 node有很多模块&#xff0c;可在node模块查看相应模块&#xff1b; var fsrequire(fs)fs.readFile(./src/a.doc,utf8,function(err,data){// 如果发生错误&#xff0c;data是undefined 如果成功 err为null console.log(err); console.log(data); }) 2.写文件 var…

ConcurrentHashMapRedis实现二级缓存

1. 为什么使用ConcurrentHashMap&#xff1f;在Java中&#xff0c;ConcurrentHashMap 是一个线程安全且高效的哈希表实现&#xff0c;广泛用于高并发场景。将其用作一级缓存的原因主要包括以下几点&#xff1a;1.1. 线程安全性ConcurrentHashMap 是线程安全的&#xff0c;支持多…

Mysql集群技术

实验在RHEL7中做&#xff0c;因为9中缺少了一个关键的高可用组件环境&#xff1a;两台数据库&#xff0c;内存和CPU要多一点主流是MYSQL&#xff08;开源&#xff09;&#xff0c;Oracle收费较贵RHEL7中直接用make编译是有问题的&#xff0c;所以需要要gcc工具做好前置准备&…

自动驾驶嵌入式软件工程师面试题【持续更新】

文章目录前言请描述 CAN 帧的基本结构&#xff08;包括标识符、数据字段、CRC 等&#xff09;描述 WebSocket 协议的基本工作流程&#xff08;包括握手、数据帧结构&#xff09;请说明如何实现 WebSocket 连接的心跳机制以检测连接状态&#xff0c;并描述在断开后如何通过重连策…

vue(5)-组件

一.组件三大组成部分&#xff08;结构/样式/逻辑&#xff09;&#xff08;1&#xff09;组件样式冲突用scoped全局样式在组件中起全局作用&#xff0c;局部样式可以加scoped属性来只作用于当前组件图中只给baseone加这个样式&#xff0c;就在baseone中style加scoped&#xff08…

【机器学习】两大线性分类算法:逻辑回归与线性判别分析:找到分界线的艺术

文章目录一、核心概念&#xff1a;数据分类的"切分线"二、工作原理&#xff1a;从"找分界线"理解二、常见算法1、逻辑回归&#xff1a;二分类2、线性判别分析&#xff08;LDA&#xff09;&#xff1a;分类与降维3、两种算法对比分析三、实际应用&#xff1…

静态分析c/cpp源码函数调用关系图生成

calltree calltree 不好使用 Dpxygen https://www.doxygen.nl/download.html Graphviz https://graphviz.org/download/ 静态代码调用结构图分析、构建、生成 doxygen doxygen在win和linux上均可运行&#xff0c;可以自动分析源码&#xff0c;对c语言项目友好&#xff0c;预处…

使用 MySQL Shell 进行 MySQL 单机到 InnoDB Cluster 的数据迁移实践

迁移背景与环境原来都是用mysqldump&#xff0c;DTS或者cdc迁移&#xff0c;这次8.0用了下新工具感觉挺好用的&#xff0c;简单快捷&#xff0c;30G数据不到源环境&#xff1a;单机 MySQL 8.0&#xff0c;地址为 172.23.3.28目标环境&#xff1a;InnoDB Cluster 集群&#xff0…

淘宝商品API可以获取哪些商品详情数据?

商品详情页商品全部sku信息"skus": {"sku": [{"price": 45.6,"total_price": 0,"orginal_price": 45.6,"properties": "1627207:39617249736","properties_name": "1627207:39617249736…

新一代PLC控制软件平台EsDA-AWStudio

在工业自动化和智能制造领域&#xff0c;高效的软件平台是提升开发效率和系统性能的关键。ZLG致远电子推出的EsDA-AWStudio平台&#xff0c;凭借其强大的功能和灵活的设计&#xff0c;为工业控制和物联网应用提供了全新的解决方案。一站式PLC工业控制软件平台EsDA-AWStudioZLG致…

基于深度学习的医学图像分析:使用MobileNet实现医学图像分类

前言 医学图像分析是计算机视觉领域中的一个重要应用&#xff0c;特别是在医学图像分类任务中&#xff0c;深度学习技术已经取得了显著的进展。医学图像分类是指将医学图像分配到预定义的类别中&#xff0c;这对于疾病的早期诊断和治疗具有重要意义。近年来&#xff0c;MobileN…

docker 容器常用命令

在平常的开发工作中&#xff0c;我们经常需要使用 docker 容器&#xff0c;那么常用的 docker 容器命令有哪些呢&#xff1f;今天简单总结下。 一&#xff1a;查看容器查看运行的容器&#xff1a;docker ps查看所有的容器&#xff1a;docker ps a查看容器详细信息&#…

重型机械作业误伤预警响应时间缩短80%!陌讯多模态识别算法在工程现场的应用优化

一、行业痛点&#xff1a;机械作业场景的识别困境据《工程机械安全白皮书&#xff08;2025&#xff09;》统计&#xff0c;施工现场因机械盲区导致的工伤事故中​​78.3%由识别延迟引发​​。核心难点包括&#xff1a;​​动态遮挡问题​​&#xff1a;吊臂摆动导致目标部件部分…

2025年ESWA SCI1区TOP,强化学习多目标灰狼算法MOGWO-RL+分布式混合流水车间调度,深度解析+性能实测

目录1.摘要2.问题描述和数学建模3.强化学习多目标灰狼算法MOGWO-RL4.结果展示5.参考文献6.算法辅导应用定制读者交流1.摘要 本文针对大规模个性化制造&#xff08;MPM&#xff09;中的调度问题&#xff0c;提出了一种新的解决方案。MPM能够在确保大规模生产的前提下&#xff0…

Mac 系统下安装 nvm

Mac 系统下安装 nvm nvm 全称为 node version manger&#xff0c;顾名思义就是管理 node 版本的一个工具&#xff0c;通过这个工具&#xff0c;我们可以在一台计算机上安装多个版本的 node&#xff0c;并且随时进行无缝的切换。 1. 卸载原本的 node.js&#xff08;重要&#xf…

变量筛选—随机森林特征重要性

对于接触算法模型不久的小伙伴来说,建模中海量变量筛选总是让人头疼,不知道如何把握。之前已经介绍了一些变量筛选的方法:变量筛选一张图、【变量筛选】计算类别型变量IV值、KS值、一文囊括风控建模中的变量筛选方法、变量筛选—特征包含信息量。本文详细介绍通过随机森林算…

【设计模式】 3.设计模式基本原则

单一职责原则 对于一个类而言&#xff0c;有且仅有一个引起他变化的原因或者说&#xff0c;一个类只负责一个职责 如果一个类承担的职责过多&#xff0c;那么这些职责放在一起耦合度太高了&#xff0c;一个职责的变化可能会影响这个类其他职责的能力。 所以我们在做软件设计的时…

ABP VNext + Redis Bloom Filter:大规模缓存穿透防护与请求去重

ABP VNext Redis Bloom Filter&#xff1a;大规模缓存穿透防护与请求去重 &#x1f680; &#x1f4da; 目录ABP VNext Redis Bloom Filter&#xff1a;大规模缓存穿透防护与请求去重 &#x1f680;TL;DR ✨1. 引言 &#x1f389;2. 环境与依赖 &#x1f6e0;️3. Bloom Filt…

构建工具和脚手架:从源码到dist

构建工具和脚手架&#xff1a;从源码到dist**1. 为什么需要工程转换&#xff1f;****2. 构建工具的核心职责**为什么要求转换**1&#xff09;明确三种关键问题****&#xff08;2&#xff09;Webpack 的打包机制****3. 开发服务器&#xff08;Webpack Dev Server&#xff09;***…

数字化生产管理系统设计

下面提供一个基于Python的数字化管理系统框架&#xff0c;使用现代技术栈实现。这个系统将包含设备监控、故障管理、装配配套表生成、生产计划管理等功能。系统架构数字化生产管理系统 ├── 设备监控模块 ├── 故障管理模块 ├── 产品装配管理模块 ├── 生产计划管理模…