设计模式-PIMPL 模式
PIMPL(Pointer to IMPLementation),又称Opaque Pointer模式或编译防火墙,是一种在C++中广泛应用的编程技术。其核心思想是将类的实现细节从公共接口中分离出来,通过指向实现类的指针来访问类的具体功能。这种模式在提高代码的可维护性、二进制兼容性和减少编译依赖方面表现出了显著的优势。
一、PIMPL 模式的原理
PIMPL模式通过两个主要的类来实现:接口类(Interface Class)和实现类(Implementation Class)。
- 接口类:这是用户使用的类,包含公共接口(即类的公有成员函数)。在接口类的头文件中,只声明一个指向实现类的私有指针(如
std::unique_ptr<Impl>),并通过这个指针来调用实现类中的成员函数。 - 实现类:包含类的实现细节和私有成员,它只在.cpp文件中定义,不暴露给外部用户。实现类通过接口类中的指针被调用,实现了接口与实现的分离。
这种分离机制使得接口类的头文件更加简洁,减少了头文件之间的依赖关系,提高了编译效率。同时,由于实现类的定义被隐藏在.cpp文件中,外部用户无法直接访问或修改实现细节,增强了代码的安全性和稳定性。
二、PIMPL 模式的应用场景
PIMPL模式在多种场景下表现出色,特别是在以下情况下尤为适用:
- 大型库或框架开发:如Qt、Boost等大型库通过PIMPL模式隔离实现细节,确保使用者不受实现变动的影响。
- 需要保持ABI稳定性:对于需要长期维护二进制兼容性的库开发,PIMPL模式允许在不改变接口的情况下修改实现。
- 减少头文件依赖:对于大型项目,通过PIMPL模式减少头文件依赖,可以显著减少编译时间。
三、PIMPL 模式的优缺点
优点
- 提高二进制兼容性:由于接口类和实现类之间的松耦合关系,实现类的变化不会影响到依赖于接口类的二进制代码。
- 减少编译依赖:通过只在头文件中声明指向实现类的指针,减少了头文件之间的依赖关系,加快了编译速度。
- 隐藏实现细节:实现了接口与实现的分离,增强了代码的安全性和稳定性。
- 支持动态加载:在某些情况下,可以通过动态加载库来实现类的具体实现,提高系统的灵活性和可扩展性。
缺点
- 性能开销:由于使用指针进行间接访问,增加了访问成本。
- 内存使用:每个实例都包含一个指向实现类的指针,增加了内存占用。
- 复杂性增加:需要维护两个类,增加了代码的复杂性。
- 调试难度:实现细节被隐藏,增加了调试的难度。
C++ 使用示例
以下是一个简单的C++示例,展示了PIMPL模式的应用。
// Book.h
#pragma once
#include <memory>class BookImpl; // 前向声明实现类class Book {
public:Book(const std::string& title, const std::string& author);~Book();void open();void close();std::string getTitle() const;std::string getAuthor() const;private:std::unique_ptr<BookImpl> pImpl; // 指向实现的指针
};// Book.cpp
#include "Book.h"class BookImpl {
public:BookImpl(const std::string& title, const std::string& author): title_(title), author_(author) {}void open() { /* 实现打开书籍的具体逻辑 */ }void close() { /* 实现关闭书籍的具体逻辑 */ }std::string getTitle() const { return title_; }std::string getAuthor() const { return author_; }private:std::string title_;std::string author_;
};Book::Book(const std::string& title, const std::string& author): pImpl(std::make_unique<BookImpl>(title, author)) {}Book::~Book() = default;void Book::open() { pImpl->open(); }
void Book::close() { pImpl->close(); }std::string Book::getTitle() const { return pImpl->getTitle(); }
std::string Book::getAuthor() const { return pImpl->getAuthor(); }// main.cpp
#include "Book.h"
#include <iostream>int main() {Book book("C++ Primer", "Stanley B. Lippman");book.open();std::cout << "Title: " << book.getTitle() << ", Author: " << book.getAuthor() << std::endl;book.close();return 0;
}
在这个示例中,Book 类是接口类,它包含公共接口和一个指向 BookImpl 实现类的指针。BookImpl 类在 Book.cpp 文件中定义,并包含了 Book 类的所有实现细节。通过这种方式,我们实现了接口与实现的分离,提高了代码的可维护性和二进制兼容性。
相关文章:
设计模式-PIMPL 模式
PIMPL(Pointer to IMPLementation),又称Opaque Pointer模式或编译防火墙,是一种在C中广泛应用的编程技术。其核心思想是将类的实现细节从公共接口中分离出来,通过指向实现类的指针来访问类的具体功能。这种模式在提高代…...
Docker部署MongoDB教程
嘿,大家好!今天我在三丰云免费服务器上进行了一次激动人心的MongoDB部署测试。这款免费云服务器1核CPU、1G内存、10G硬盘、5M带宽,是不错的免费服务器选择。 首先,让我们简要介绍一下使用到的Docker和MongoDB软件。Docker是一个开…...
堆排序易错点
1.建堆和调整堆(插入和删除) 建堆和调整堆的过程是不一样的: 建堆 从非终端节点编号的结点开始依次建立大根堆,例如: 拿第2个图说,首先比较-1,7,从中选一个小的,即“-1”…...
安卓13长按电源按键直接关机 andriod13不显示关机对话框直接关机
总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 有些设备需要在长按电源键的时候,直接关机。不需要弹出对话框进行询问。 2.问题分析 过滤电源按键,需要在系统里面处理的话,那么我们需要熟悉android的事件分发,然后再…...
React学习笔记(四)——React 组件生命周期
目录 1. 生命周期-概览 2. 生命周期-挂载阶段 3. 生命周期-更新阶段 4. 生命周期-卸载阶段 5. setState扩展-发现问题 6. setState扩展-更多用法 7. setState扩展-异步 1. 生命周期-概览 了解react类组件生命周期整体情况 大致步骤: 什么是生命周期React类组…...
PHP的guzzlehttp/guzzle库在碰到各种异常时的场景
PHP的guzzlehttp/guzzle库在碰到各种异常时的场景 结论: 经过测试得知 在http状态码为1xx, 2xx, 3xx时, 会在111处输出返回 在http状态码为4xx, 5xx时, 会在222处被捕获 在目标服务不可达或其他异常时会在333处被捕获 测试过程: 用其他程序写个接口, 实现输入什么状态码就返…...
多机部署,负载均衡-LoadBalance
文章目录 多机部署,负载均衡-LoadBalance1. 开启多个服务2. 什么是负载均衡负载均衡的实现客户端负载均衡 3. Spring Cloud LoadBalance快速上手使用Spring Cloud LoadBalance实现负载均衡修改IP,端口号为服务名称启动多个服务 负载均衡策略自定义负载均衡策略 LoadBalance原理…...
Hadoop安装与配置
一、Hadoop安装与配置 1、解压Hadoop安装包 找到hadoop-2.6.0.tar.gz,将其复到master0节点的”/home/csu”目录内,解压hadoop [csumaster0 ~]$ tar -zxvf ~/hadoop-2.6.0.tar.gz 解压成成功后自动在csu目录下创建hadoop-2.6.0子目录,可以用cd hadoo…...
一个自制的比较low的刷题软件
一个自制的比较low的刷题软件 一、背景 工作中往往涉及一些考试,比如阿里云ACP认证,华为GAUSS认证、软考等,应对这些考试的时候,我们往往是先看书后刷题(当然也有直接刷题的大神,毕竟考试,懂的…...
【Java 集合】List接口 —— ArrayList 与 LinkedList 详解
List接口继承自Collection接口,是单列集合的一个重要分支。 在List集合中允许出现重复的元素,所有的元素是以一种线性方式进行存储的,在程序中可以通过索引(类似于数组中的元素角标)来访问集合中的指定元素。另外&…...
通信工程学习:什么是PNF物理网络功能
PNF:物理网络功能 PNF(Physical Network Function)即物理网络功能,是指支持网络功能的物理设备。以下是关于PNF的详细解释: 一、定义与特点 定义: PNF是网络设备厂商(如Cisco、华为、H3C等)通过专用硬件实体提供软件功能的设备。这些设备直接在物理服务器上运…...
Unity的Text组件中实现输入内容的渐变色效果
要在Unity的Text组件中实现输入内容的渐变色效果,默认的Text组件不直接支持渐变色。但是,你可以通过以下几种方式实现: ### 1. **使用Shader**来实现渐变效果 通过自定义Shader为Text组件创建一个渐变效果。这是一个常用的做法࿰…...
network-scripts目录下没有ens33文件的问题
作者:程序那点事儿 日期:2023/11/09 06:52 systemctl start NetworkManager #开启网络管理器nmcli con show #查看ens33网卡对应的是ifcfg-Wired_connection_3这个文件(网络管理器要开启,不然报错),或者根据…...
OpenHarmony(鸿蒙南向)——平台驱动指南【DAC】
往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ 持续更新中…… 概述 功能简介 DAC(Digital to Analog Converter&…...
10.Lab Nine —— file system-下
Symbolic links 添加符号链接 1.添加有关symlink系统调用的定义声明,包括kernel/syscall.h, kernel/syscall.c, user/usys.pl 和 user/user.h. 2.添加新的文件类型T_SYMLINK到kernel/stat.h中,添加新的文件标识位O_NOFOLLOW到kernel/fcntl.h中 3.在ken…...
低代码中实现数据映射的必要性与方案
在数字化转型的浪潮中,低代码平台因其快速开发和灵活性而受到越来越多企业的青睐。然而,随着业务需求的复杂化,单纯依赖低代码工具往往难以满足企业在数据处理和业务逻辑上的要求。数据映射作为连接不同数据源和业务逻辑的桥梁,显…...
SpringBoot集成阿里easyexcel(一)基础导入导出
easyexcel主要用于excel文件的读写,可使用model实体类来定义文件读写的模板,对开发人员来说实现简单Excel文件的读写很便捷。可参考官方文档 https://github.com/alibaba/easyexcel 一、引入依赖 <!-- 阿里开源EXCEL --><dependency><gr…...
四元组问题
目录 问题描述 输入格式 输出格式 样例输入 样例输出 说明 评测数据规模 运行限制 原题链接 代码思路 问题描述 从小学开始,小明就是一个非常喜欢数学的孩子。他喜欢用数学的方式解决各种问题。在他的高中时期,他遇到了一个非常有趣的问题&…...
如何用Prometheus监控禁用了Actuator的SpringBoot?
需求来源 prometheus监控微服务一般都是使用micrometer结合actuator来做: 添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId> </dependency> <d…...
使用TensorFlow实现一个简单的神经网络:从入门到精通
使用TensorFlow实现一个简单的神经网络:从入门到精通 在现代数据科学和机器学习领域,神经网络是一个非常重要的工具。TensorFlow 是一个开源的深度学习框架,由 Google 开发和维护,它使得构建和训练神经网络变得更加容易。本文将详细介绍如何使用 TensorFlow 实现一个简单的…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道
文/法律实务观察组 在债务重组领域,专业机构的核心价值不仅在于减轻债务数字,更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明,合法债务优化需同步实现三重平衡: 法律刚性(债…...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
