谈谈《More Effective C++》的条款30:代理类

在《More Effective C++》的条款30中,Scott Meyers深入探讨了**代理类(Proxy Classes)**的设计与应用。代理类是一种通过重载运算符模拟原始对象行为的设计模式,其核心目标是在不直接暴露原始对象的情况下,提供额外功能、控制访问或优化性能。以下是条款30的核心内容与实践要点:

一、代理类的核心作用

代理类通过运算符重载(如operator[]operator())拦截对原始对象的访问,并在背后执行特定逻辑。常见应用场景包括:

  1. 延迟计算(Lazy Evaluation)
    代理类可推迟实际对象的创建或计算,直到真正需要时才执行。例如,二维数组的代理类可在访问元素时动态计算索引,避免预先分配全部内存。
  2. 边界检查与安全性增强
    在访问数组元素时,代理类可检查索引是否越界。例如,Array2Doperator()返回Array1D代理对象,后者的operator[]执行边界验证,确保操作安全。
  3. 只读访问控制
    通过代理类区分读写操作。例如,vector<bool>reference代理类在赋值时执行写操作,而隐式转换为bool时仅允许读操作,防止意外修改。
  4. 隐藏实现细节
    代理类可封装复杂实现,仅暴露必要接口。例如,通过interface代理类隐藏implementation类的私有数据,客户端仅需与代理类交互。

二、实现代理类的关键技术

1. 运算符重载的灵活运用
  • operator[]operator()
    代理类常通过重载这两个运算符实现元素访问。例如:

    class Array1D {
    public:int& operator[](size_t index) { /* 边界检查 + 返回实际元素 */ }
    };class Array2D {
    public:Array1D operator()(size_t row) { /* 返回行代理对象 */ }
    };
    // 使用:Array2D arr; arr(3)[6] = 42; (两次运算符调用)
    

    此处Array2D::operator()返回Array1D代理对象,后者的operator[]执行最终操作。

  • operator->与智能指针
    代理类可模拟指针行为,例如智能指针RCPtr(引用计数指针)通过operator->访问原始对象,同时管理资源生命周期。

2. 模板与泛型设计

代理类常结合模板实现通用性。例如,延迟加载的Proxy<T>类可包装任意类型:

template <typename T>
class Proxy {
private:T* data = nullptr;std::string filePath;
public:T& operator*() {if (!data) data = loadFromDisk(filePath); // 首次访问时加载return *data;}
};

这种设计允许对大对象(如图像、数据库记录)进行按需加载,避免内存浪费。

3. 引用计数与资源管理

代理类可与条款29的**引用计数指针(RCPtr)**结合,实现线程安全的资源共享。例如:

class StringValue;
typedef RCPtr<StringValue> String; // 代理类管理字符串资源
String s = "hello"; // 隐式转换为代理对象

RCPtr确保字符串仅在最后一个代理对象销毁时释放内存。

三、代理类的典型应用示例

1. 二维数组的安全访问

通过嵌套代理类实现多级访问控制:

class Array1D {
private:std::vector<int>& data;size_t row;
public:int& operator[](size_t col) { return data[row * cols + col]; }
};class Array2D {
private:std::vector<int> data;size_t rows, cols;
public:Array1D operator()(size_t row) { return Array1D(data, row, cols); }
};

Array2Doperator()返回Array1D代理对象,后者的operator[]执行行列计算,避免越界访问。

2. 只读与读写分离

通过代理类区分读写操作:

class ConstStringProxy {
public:operator std::string() const { return realString; }
};class String {
public:ConstStringProxy operator[](size_t index) const { /* 返回只读代理 */ }char& operator[](size_t index) { /* 返回可写引用 */ }
};

String对象为const时,operator[]返回ConstStringProxy,禁止修改;非const时返回原始引用,允许修改。

四、代理类的优缺点与注意事项

优点
  • 封装与抽象:隐藏复杂实现,降低客户端代码复杂度。
  • 安全性:通过边界检查、只读控制等增强鲁棒性。
  • 性能优化:延迟计算减少不必要的资源消耗。
缺点
  • 性能开销:额外的运算符调用可能降低高频访问场景的效率。
  • 代码复杂性:需处理运算符重载、对象生命周期等细节。
  • 隐式转换限制:代理类可能需要限制隐式转换,避免意外行为(如vector<bool>::reference无法取地址)。
实践建议
  1. 谨慎使用隐式转换
    代理类应明确控制转换行为,避免与原始类型混淆。例如,vector<bool>reference代理类仅允许转换为bool,但禁止转换为bool&
  2. 结合pimpl idiom
    通过pimpl(指针到实现)模式将代理类的实现细节隐藏在.cpp文件中,减少编译依赖。
  3. 权衡性能与功能
    在高频访问场景(如循环)中,需评估代理类的开销是否可接受。必要时可提供非代理版本作为备选。

总结

代理类是C++中一种强大的抽象工具,通过运算符重载实现对原始对象的灵活控制。

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

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

相关文章

实用AI在线开发工具网址汇总(含免费限额,国内可访)

AI在线开发工具 标题分类属性在线开发工具1https://www.builder.io/介绍详见&#xff1a;AI在线编码三剑客对决&#xff1a;Replit/Builder/Blot在线开发工具2https://replit.com/介绍详见&#xff1a;AI在线编码三剑客对决&#xff1a;Replit/Builder/Blot在线开发工具3https…

react+vite来优化下每次使用hook函数都要引入的情况

前言&#xff1a;react项目中&#xff0c;每个页面都得引入react/react-dom等元素&#xff0c;就像uniapp的项目中得onload,onshow等生命周期一样&#xff0c;这里也可以用vite的插件&#xff1a;unplugin-auto-import 来解决我们每次都需要调用才能使用hook方法的问题。安装&a…

【排序算法】⑤冒泡排序

系列文章目录 第一篇&#xff1a;【排序算法】①直接插入排序-CSDN博客 第二篇&#xff1a;【排序算法】②希尔排序-CSDN博客 第三篇&#xff1a;【排序算法】③直接选择排序-CSDN博客 第四篇&#xff1a;【排序算法】④堆排序-CSDN博客 第五篇&#xff1a;【排序算法】⑤冒…

如何使用gpt进行模式微调(2)?

对 GPT&#xff08;Generative Pre-trained Transformer&#xff09;类大模型进行微调&#xff08;Fine-tuning&#xff09;&#xff0c;是将其适配到特定任务或领域的关键步骤。以下是 ​​全流程指南​​&#xff0c;涵盖方法选择、数据准备、训练配置、评估部署等核心环节&a…

基于飞算JavaAI实现图书管理系统框架部署

摘要 本文详细介绍了如何利用飞算JavaAI技术实现图书管理系统的框架部署。首先阐述了飞算JavaAI的基本概念、特点和优势&#xff0c;接着对图书管理系统的需求进行分析&#xff0c;然后按照软件开发流程&#xff0c;从系统设计、代码生成、框架搭建到部署测试&#xff0c;逐步展…

ODE-by-Matlab-01-人口增长模型

博客地址&#xff1a;Matlab微分方程01-模型 马尔萨斯模型 马尔萨斯模型是人口增长模型中最简单的模型&#xff0c;它由英国牧师家马尔萨斯在1798年提出。 他利用在教堂工作的机会&#xff0c;收集英国100多年的人口数据&#xff0c;发现人口的相对增长率是常数。 在这个基础…

云原生环境 Prometheus 企业级监控实战

目录 一&#xff1a;基于 kubernetes 的 Prometheus 介绍 1&#xff1a;环境简介 2&#xff1a;监控流程 3&#xff1a;Kubernetes 监控指标 二&#xff1a;Prometheus 的安装 1&#xff1a;从 Github 克隆项目分支 2&#xff1a;安装 Prometheus Operator --server-si…

Python爬虫实战:研究django-dynamic-scraper 框架,构建电商动态数据采集系统

1. 引言 1.1 研究背景 据 Statista 数据,2025 年全球互联网数据总量将突破 175ZB,其中 80% 为非结构化数据(网页、文本、图像等)。高效提取这些数据对企业竞争情报、学术研究至关重要。网络爬虫作为数据获取的核心工具,经历了从静态页面抓取到动态内容解析的演进,但传统…

掌握MATLAB三维可视化:从基础到实战技巧

目录 1. 引言&#xff1a;三维可视化的重要性 2. 基础三维图形绘制 2.1 三维曲线图&#xff08;plot3&#xff09; 2.2 三维散点图&#xff08;scatter3&#xff09; 2.3 三维网格图&#xff08;mesh&#xff09; 2.4 三维曲面图&#xff08;surf&#xff09; 3. 参数曲面…

Linux 服务部署:自签 CA 证书构建 HTTPS 及动态 Web 集成

Linux 服务部署&#xff1a;自签 CA 证书构建 HTTPS 及动态 Web 集成 一、HTTPS基础原理 HTTPS是HTTP协议基于SSL/TLS协议的加密版本&#xff0c;核心差异及握手过程如下&#xff1a;HTTP与HTTPS对比协议传输方式端口核心特点HTTP明文传输80无加密&#xff0c;安全性低HTTPS数据…

Python3.10 + Firecrawl 下载公众号文章

获取Firecrawl apikey 打开官网&#xff0c;使用github账号登录 https://www.firecrawl.dev/ 进入个人中心 https://www.firecrawl.dev/app/api-keys 使用PyCharm创建python项目 创建.env # API配置 FIRECRAWL_API_KEYfc-9*********0816d5ac6b20 # 输出配置 OUTPUT_DIRout…

IoT/透过oc_lwm2m/boudica150 源码中的AT指令序列,分析NB-IoT接入华为云物联网平台IoTDA的工作机制

文章目录概述指令调用顺序具体接入指令分析ATE0 关闭回显ATQREGSWT 设置&#xff08;平台&#xff09;注册模式ATQLWSREGIND0 手动注册平台set_autoconnect / ATNCONFIGATNBANDx,xset_plmn / ATCOPS_set_apn / ATCGDCONT(安全)接入参数 CDPDTLSPSKATNNMI 设置新消息指示_check_…

Android UI(一)登录注册 - Compose

UI - 登录注册 - Compose一、声明式UI1. **颠覆传统开发模式**2. **技术优势**3. **开发效率提升**4. **未来生态方向**5. **实际影响**二、创建项目1. Compose UI结构2. Scaffold3. 可组合函数三、创建组件页面1. LoginPage2. RegisterPage3. MainPage四、导航1. 添加依赖2. 使…

分享10个ai生成ppt网站(附ai生成ppt入口)

实测对比&#xff1a;15页PPT从3小时压缩到3分钟的秘密武器 当ChatGPT能写方案、Midjourney能画图&#xff0c;做PPT还在手动排版就OUT了&#xff01;这些AI生成PPT网站已实现「输入文案秒出设计稿」&#xff0c;无论职场汇报、毕业答辩还是路演融资&#xff0c;零设计基础也能…

最强开源视频模型通义万相wan2.1在comfyui中的安装应用详解

摘要&#xff1a;阿里巴巴开源通义万相Wan2.1模型&#xff0c;支持文生视频、图生视频等多种功能&#xff0c;并整合关键环节简化创作流程。官方和Kiji版本需配套使用各自工作流。低显存显卡可使用GGUF模型解决方案&#xff0c;最低适配4G显存。ComfyUI已原生支持该模型&#x…

机器学习:基于OpenCV和Python的智能图像处理 实战

机器学习&#xff1a;基于OpenCV和Python的智能图像处理实战——待填坑图像处理基础图像的基本表示方法图像处理的基本操作图像运算图像的色彩空间转换图像几何变换4.1 仿射变换4.2 重映射4.3 投影变换 4.4 极坐标变换5 图像直方图处理7 图像阈值处理8 图像形态学处理github地址…

proteus实现简易DS18B20温度计(stm32)

一、新建proteus工程 具体看前面文章 二、搭建电路 需要配置供电网络以及寻找元器件&#xff0c;细节看前面文章&#xff0c;下面给出电路图 电路包含了五个部分&#xff1a; 1、DS18B20&#xff1a;数据引脚记得上拉 2、stm32电路 3、串口电路&#xff08;右下角那个器件…

Autoppt-AI驱动的演示文稿生成工具

本文转载自&#xff1a;Autoppt-AI驱动的演示文稿生成工具 - Hello123工具导航 ** 一、 Autoppt&#xff1a;AI 驱动的智能演示文稿生成工具 Autoppt 是一款基于人工智能的在线演示文稿生成平台&#xff0c;通过输入主题或上传文档&#xff08;Word/PDF/ 图片等&#xff09;&…

Flink on YARN启动全流程深度解析

Flink on YARN 模式启动流程及核心组件协作详解整个过程分为三个主要阶段&#xff1a;​​JobManager 启动​​&#xff08;作业提交与 AM 初始化&#xff09;​​TaskManager 资源分配与启动​​​​任务部署与执行​​第一阶段&#xff1a;作业提交与 JobManager (AM) 启动​…

安卓开发者自学鸿蒙开发1基础入门

1.基础 声明式UI&#xff1a;​​ ​​核心&#xff1a;​​ 你​​声明​​你想要UI是什么样子&#xff08;在build()方法里描述&#xff09;&#xff0c;而不是一步步命令式地创建和操作View对象&#xff08;findViewById, setText, setOnClickListener&#xff09;。 模块化…