0

0

怎样实现C++的代理模式 虚拟代理与保护代理应用场景

P粉602998670

P粉602998670

发布时间:2025-07-17 08:39:03

|

817人浏览过

|

来源于php中文网

原创

代理模式的核心是通过替身控制对真实对象的访问,其目的是在不修改真实对象的前提下实现延迟加载、权限控制等额外逻辑。要实现代理模式,首先要定义共同接口subject,让realsubject和proxy都实现它;其次代理持有真实对象的引用,并在其方法中加入前置或后置处理逻辑;最后根据需求扩展虚拟代理或保护代理。虚拟代理侧重按需加载,适用于资源占用大的场景;保护代理则用于权限检查,确保系统安全。这种设计提升了系统的灵活性、可维护性与安全性。

怎样实现C++的代理模式 虚拟代理与保护代理应用场景

C++中实现代理模式,本质上是在不直接接触真实对象的情况下,通过一个“替身”来控制对真实对象的访问。虚拟代理常用于延迟加载资源,优化性能,而保护代理则侧重于访问权限控制,确保系统安全。这两种代理模式各有侧重,但都旨在提供更灵活、更安全的面向对象设计。

怎样实现C++的代理模式 虚拟代理与保护代理应用场景

要实现C++的代理模式,核心在于定义一个共同的接口(Subject),让真实对象(RealSubject)和代理对象(Proxy)都实现它。代理对象内部持有真实对象的引用,并在自己的方法中调用真实对象的方法,但在此之前或之后加入额外的逻辑。

一个典型的结构会是这样:

立即学习C++免费学习笔记(深入)”;

怎样实现C++的代理模式 虚拟代理与保护代理应用场景
#include <iostream>
#include <string>
#include <chrono> // For std::this_thread::sleep_for
#include <thread> // For std::this_thread

// 共同接口
class Subject {
public:
    virtual void request() = 0;
    virtual ~Subject() = default;
};

// 真实对象
class RealSubject : public Subject {
public:
    void request() override {
        // 真实对象执行核心业务逻辑
        // 比如:加载大型图片、执行耗时计算、访问敏感数据
        std::cout << "RealSubject: Handling request." << std::endl;
    }
};

// 代理对象基类(可以抽象出,也可以直接实现特定代理)
// 这里以一个通用的代理为例
class GeneralProxy : public Subject {
protected:
    RealSubject* realSubject; // 代理持有真实对象的引用

public:
    GeneralProxy() : realSubject(nullptr) {} // 默认构造,可能在需要时才创建RealSubject
    ~GeneralProxy() {
        delete realSubject; // 清理资源
    }

    // 代理的核心:在调用真实方法前后加入逻辑
    void request() override {
        // 这是通用代理的模板,具体代理会重写此方法
        if (!realSubject) {
            // 假设这里是虚拟代理的创建逻辑
            realSubject = new RealSubject();
            std::cout << "GeneralProxy: Creating RealSubject on demand." << std::endl;
        }
        // 在调用真实方法前可以做些什么
        std::cout << "GeneralProxy: Pre-processing request." << std::endl;
        realSubject->request();
        // 在调用真实方法后可以做些什么
        std::cout << "GeneralProxy: Post-processing request." << std::endl;
    }
};

实际应用中,虚拟代理和保护代理会在此基础上增加特有的逻辑。例如,虚拟代理会在 request 首次调用时才创建 RealSubject 实例;保护代理则会在 request 调用前检查调用者的权限。

C++代理模式的核心理念是什么,为何我们应该考虑使用它?

代理模式,说白了,就是给一个对象找个“替身”。这个替身(Proxy)和原对象(RealSubject)实现同一个接口,所以客户端代码完全不知道自己打交道的是替身还是真身。这听起来有点像在玩“障眼法”,但它的价值可不小。

怎样实现C++的代理模式 虚拟代理与保护代理应用场景

我个人觉得,代理模式最迷人的地方在于它提供了一种“间接性”的控制。我们不需要直接修改真实对象的代码,就能在它被访问时,或者访问它之后,插入各种额外的逻辑。这对于那些我们无法修改、不应该修改或者修改成本很高的第三方库、遗留系统中的类尤其有用。

Otter.ai
Otter.ai

一个自动的会议记录和笔记工具,会议内容生成和实时转录

下载

为什么要用它?想象一下,你有一个非常“重”的对象,比如加载一张几百兆的图片,或者从一个远程数据库拉取大量数据。你肯定不希望在程序启动时就把所有这些东西都加载进来,那样程序会慢得像蜗牛。这时候,代理就能派上用场了。它可以在你真正需要这些数据的时候,才去加载它们。这就是一种性能优化,一种延迟加载的策略。

再比如,你有一个核心的业务逻辑对象,但不是所有用户都能访问它的所有功能。有些功能只允许管理员操作,有些只允许普通用户查看。你当然可以在真实对象的方法里写一堆 if (user.role == ADMIN) 这样的判断,但那样会把真实对象的代码搞得一团糟,而且职责也不清晰。这时候,代理就可以在访问真实对象之前,先检查一下用户的权限。权限不够?直接拒绝访问,连真实对象一眼都看不到。这不就是一种优雅的访问控制吗?

所以,核心理念就是:通过引入一个中间层,在不改变原有接口的前提下,对真实对象的访问进行控制、增强或限制。它提供了一种解耦的方案,让我们可以把一些非核心的、横切的关注点(比如延迟加载、访问控制、日志记录、缓存等)从真实对象中剥离出来,保持真实对象的纯粹性,同时提升系统的灵活性和可维护性。在我看来,这是一种非常“面向对象”的思考方式,把职责划分得清清楚楚。

虚拟代理与其他代理有何不同,何时它能真正发挥作用?

虚拟代理,顾名思义,就是一种“假”的代理,它在开始时并不持有真实对象的实例,而是在真实对象第一次被需要时才去创建它。这与那些一开始就持有真实对象引用的代理(比如保护代理或远程代理)形成了鲜明对比。它的核心思想就是“按需加载”(Lazy Loading)。

我记得有一次,我手头一个项目需要显示一个包含大量高分辨率图片的列表。如果我直接在列表加载的时候就把所有图片都加载到内存里,那程序启动速度会非常慢,而且内存占用会爆炸。用户可能根本不会滚动到列表的底部,或者根本不会点击查看所有图片。这时候,虚拟代理简直是救星。

它的实现通常是这样的:代理对象在构造时并不会创建真实对象,而是持有一个指向真实对象类型,但初始为空的指针。当客户端代码第一次调用代理的某个方法时,代理会检查这个指针是否为空。如果为空,它就负责创建真实对象的实例,然后将后续的请求转发给这个新创建的真实对象

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

847

2023.08.22

go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

58

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

63

2025.11.27

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1960

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

658

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2401

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

47

2026.01.19

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

447

2023.07.18

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.3万人学习

C 教程
C 教程

共75课时 | 5.4万人学习

C++教程
C++教程

共115课时 | 21.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号