当前位置: 首页 > article >正文

C++ 编程指南36 - 使用Pimpl模式实现稳定的ABI接口

一:概述

        C++ 的类布局(尤其是私有成员变量)直接影响它的 ABI(应用二进制接口)。如果你在类中添加或修改了私有成员,即使接口不变,编译器生成的二进制布局也会变,从而导致 ABI 不兼容。这意味着使用这个类的代码需要重新编译,严重破坏了库的二进制兼容性。为避免这种情况,Pimpl(Pointer to Implementation) 模式应运而生。

二:Pimpl 模式介绍

        Pimpl将类的实际实现细节封装在另一个类中(impl),对外只暴露一个指向实现的智能指针(如 std::unique_ptr<impl>)。这样你可以随意修改实现类而不会影响主类的 ABI,因为指针大小在所有平台都是固定的。

三:代码示例

        widget.h 为对外公开的接口文件:

class widget {class impl; // 前向声明实现类std::unique_ptr<impl> pimpl; // 指向实现的指针public:void draw();       // 接口函数,转发到实现widget(int);       // 构造函数:传参数给实现~widget();         // 析构函数:释放实现widget(widget&&) noexcept;widget(const widget&) = delete;widget& operator=(widget&&) noexcept;widget& operator=(const widget&) = delete;
};

        widget.cpp 为实现细节,隐藏在此文件中:

class widget::impl {int n;  // 实际的成员变量
public:void draw(const widget& w) { /* ... */ }impl(int n) : n(n) {}
};

        用户视角:

widget w(42);   // 实际构造 impl(42)
w.draw();       // 实际转发给 impl->draw()

 四:总结

       我们可以把这个规则理解为:将实现藏进“黑匣子”,只留遥控器给别人用。

相关文章:

C++ 编程指南36 - 使用Pimpl模式实现稳定的ABI接口

一&#xff1a;概述 C 的类布局&#xff08;尤其是私有成员变量&#xff09;直接影响它的 ABI&#xff08;应用二进制接口&#xff09;。如果你在类中添加或修改了私有成员&#xff0c;即使接口不变&#xff0c;编译器生成的二进制布局也会变&#xff0c;从而导致 ABI 不兼容。…...

Linux中的文件传输(附加详细实验案例)

一、实验环境的设置 ①该实验需要两台主机&#xff0c;虚拟机名称为 L2 和 L3 &#xff0c;在终端分别更改主机名为 node1 和 node2&#xff0c;在实验过程能够更好分辨。 然后再重新打开终端&#xff0c;主机名便都更改了相应的名称。 ②用 ip a 的命令分别查看两个主机的 …...

基于 OpenHarmony 5.0 的星闪轻量型设备应用开发——Ch2 OpenHarmony LiteOS-M 内核应用开发

写在前面&#xff1a; 此篇是系列文章《基于 OpenHarmony5.0 的星闪轻量型设备应用开发》的第 2 章。本篇介绍了如何在 OpenHarmony 5.0 框架下&#xff0c;针对 WS63 进行 LiteOS-M 内核应用工程的开发。 为了方便读者学习&#xff0c;需要OpenHarmony 5.0 WS63 SDK 的小伙伴可…...

论文阅读:2024-arxiv How to Steer LLM Latents for Hallucination Detection?

总目录 大模型安全相关研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 How to Steer LLM Latents for Hallucination Detection? https://arxiv.org/pdf/2503.01917 https://www.doubao.com/chat/2818934852496130 其它资料: https://blog.csdn.net/we…...

Linux--线程概念与控制

目录 1. Linux线程概念 1-1 什么是线程 1-2 分⻚式存储管理 1-2-1 虚拟地址和⻚表的由来 1-2-2 物理内存管理 1-2-3 ⻚表 1-2-4 ⻚⽬录结构 1-2-5 两级⻚表的地址转换 1-2-6 缺⻚异常 1-3 线程的优点 1-4 线程的缺点 1-5 线程异常 1-6 线程⽤途 2. Linux进程VS线…...

Python | kelvin波的水平空间结构

写在前面 简单记录一下之前想画的一个图&#xff1a; 思路 整体比较简单&#xff0c;两个子图&#xff0c;本质上就是一个带有投影&#xff0c;一个不带投影&#xff0c;通常用在EOF的空间模态和时间序列的绘制中&#xff0c;可以看看之前的几个详细的画法。 Python | El Ni…...

【音视频】SDL播放PCM音频

相关API 打开音频设备 int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained); desired&#xff1a;期望的参数。obtained&#xff1a;实际音频设备的参数&#xff0c;一般情况下设置为NULL即可。 SDL_AudioSpec typedef struct SDL_AudioSpec { i…...

BERT - Bert模型框架复现

本节将实现一个基于Transformer架构的BERT模型。 1. MultiHeadAttention 类 这个类实现了多头自注意力机制&#xff08;Multi-Head Self-Attention&#xff09;&#xff0c;是Transformer架构的核心部分。 在前几篇文章中均有讲解&#xff0c;直接上代码 class MultiHeadAtt…...

【LeetCode 热题100】二叉树遍历入门:从中序遍历到层序与右视图(力扣94 / 102/199)(Go语言版)

&#x1f333; 二叉树遍历入门&#xff1a;从中序遍历到层序与右视图 本文涵盖 LeetCode 上的三道基础但极具代表性的二叉树遍历题&#xff1a; 二叉树的中序遍历 二叉树的层序遍历 二叉树的右视图 通过这些题目&#xff0c;我们将从 DFS 到 BFS&#xff0c;深入理解如何处理…...

docker创建容器添加启动--restart选项

一、通过 Docker 命令直接修改已启动的容器&#xff08;推荐-已验证&#xff09; 操作步骤&#xff1a; 1.执行更新命令&#xff1a; docker update --restartalways <容器名或ID>此命令会将容器的重启策略调整为 always&#xff08;无论容器以何种状态退出&#xff0…...

一文读懂WPF系列之常用控件以及样式

WPF控件 控件分类概览常用控件常用控件代码示例和效果 样式与模板应用样式定义​​方式行内样式​​页面/窗口级资源样式&#xff08;Local Resource&#xff09;应用程序全局资源独立资源字典&#xff08;ResourceDictionary&#xff09;控件模板&#xff08;ControlTemplate&…...

嵌入式硬件篇---单片机周期

文章目录 前言 前言 在单片机中&#xff0c;时序控制是其执行指令和协调外设的核心基础。以下是单片机中常见的各种周期及其详细说明&#xff0c;以层次结构展开&#xff1a; 时钟周期&#xff08;Clock Cycle&#xff09; 定义&#xff1a; 时钟周期是单片机的最小时间单位&a…...

【双指针】专题:LeetCode 283题解——移动零

移动零 一、题目链接二、题目三、题目解析四、算法原理两个指针的作用以及三个区间总结 五、与快速排序的联系六、编写代码七、时间复杂度、空间复杂度 一、题目链接 移动零 二、题目 三、题目解析 “保持非零元素的相对顺序”&#xff0c;比如&#xff0c;示例1中非零元素1…...

2025蓝桥杯JavaB组

说明 博主自己水平有限&#xff0c;而且答案也不一定对&#xff0c;下面代码和思路仅作分享。我只把我考场上做了的写出来了&#xff0c;有什么问题欢迎评论区交流。 A&#xff1a;逃离高塔 思路&#xff1a; 由于有了去年的经验&#xff0c;所以一上来我就是找规律&#xf…...

SQL学习--基础语法学习

SQL和excle对比 学习目标 单表查询 项目背景 SQL 练习环境 SQL Online Compiler - Next gen SQL Editor 商品信息表&#xff1a;https://study-zhibo.oss-cn-shanghai.aliyuncs.com/test/%E5%95%86%E5%93%81%E4%BF%A1%E6%81%AF%E8%A1%A8.csv 订单明细表&#xff1a;https://…...

MATLAB2022b安装

1 从百度网盘下载MATLAB2022b&#xff0c;下载完成后解压到某个文件夹&#xff1b; 链接: MATLAB2022b 提取码: 6666 2 打开解压后的文件夹&#xff0c;进入setup文件夹&#xff0c;双击打开“setup.exe”文件&#xff1b; 3 在弹出窗口中选择“高级选项”-->“我有文件安…...

如何更改OCP与metadb集群的连接方式 —— OceanBase运维管理

背景 许多用户都会借助OCP平台来进行OceanBase集群的运维与监控&#xff0c;且因为考虑单节点的OCP部署&#xff0c;在遇故障时可能会短时间出现无法管控 OceanBase集群&#xff0c;多数用户倾向于采用多节点方式来部署OCP&#xff0c;即 OCP的 metadb集群也是三节点的集群部署…...

HTTP实现心跳模块

HTTP实现心跳模块 使用轻量级的cHTTP库cpp-httplib重现实现HTTP心跳模块 头文件HttplibHeartbeat.h #ifndef HTTPLIB_HEARTBEAT_H #define HTTPLIB_HEARTBEAT_H#include <string> #include <thread> #include <atomic> #include <chrono> #include …...

架构总览怎么写,才算工业级?

📈系统架构文档是整个项目最重要的起点,但很多人第一章就“写穿了”: 不是写得太细,就是没有重点。想要写出高质量、能协作、能传承的架构文档,这一篇会告诉你应该怎么做—— ✅ 架构总览的终极目标 明确边界、定义角色、画清数据流 别讲执行细节,别深入函数调用。 ✅ 架…...

Python10天突击--Day 3:函数式编程突破

以下是 Python 中实现方法耗时统计装饰器的完整方案&#xff0c;包含同步/异步支持、多级嵌套调用统计、可视化输出和性能分析等高级功能&#xff1a; 基础版&#xff1a;同步方法计时装饰器 import time from functools import wrapsdef timeit(func):"""基础…...

Datawhale 入驻 GitCode:以开源力量推动 AI 教育公平与创新

在 AI 技术深度重塑教育生态的今天&#xff0c;国内首个 AI 开源学习社区 —— Datawhale 正式加入 GitCode 开源平台&#xff01;作为覆盖全球 3000 高校、培养超百万 AI 人才的创新社区&#xff0c;Datawhale 将通过开源协作模式&#xff0c;为人工智能教育公平注入新动能&a…...

ChatDBA:一个基于AI的智能数据库助手

今天给大家介绍一个基于 AI 大语言模型实现数据库故障诊断的智能助手&#xff1a;ChatDBA。 ChatDBA 是由上海爱可生信息技术股份有限公司开发&#xff0c;通过对话交互&#xff0c;提供数据库故障诊断、专业知识学习、SQL 生成和优化等功能&#xff0c;旨在提升 DBA 工作效率。…...

MacOS中的鼠标、触控板的设置研究

一、背景和写这篇文章的原因 想搞清楚和配置好鼠标&#xff0c;比如解决好为什么我的滚动那么难用&#xff1f;怎么设置滚轮的方向跟windows相同&#xff1f;调整双击速度&#xff0c;调整鼠标滚轮左右拨动的"冷却时间"。 二、各种设置之详细解释 1. MacOS设置 -&…...

asp.net core 项目发布到 IIS 服务器

目录 一、VS2022 发布 二、设置IIS服务 三、配置IIS管理器 &#xff08;一&#xff09;打开IIS管理器 &#xff08;二&#xff09;添加站台 &#xff08;三&#xff09;配置应用程式集区 四、安装ASP.NET Core Hosting Bundle 五、设定IIS的日志位置 六、测试 一、VS2…...

如何解决线程安全问题(不涉及分布式情况)

线程安全问题本质 当多个线程并发操作共享资源&#xff08;变量/对象&#xff09;时&#xff0c;可能因非原子性操作或内存可见性问题导致数据不一致。 解决方案一&#xff1a;synchronized 关键字 ‌实现方式&#xff1a;‌ ‌实例方法同步锁‌ 在实现Runnable接口的自定义线…...

Spring Boot(二十二):RedisTemplate的List类型操作

RedisTemplate和StringRedisTemplate的系列文章详见&#xff1a; Spring Boot&#xff08;十七&#xff09;&#xff1a;集成和使用Redis Spring Boot&#xff08;十八&#xff09;&#xff1a;RedisTemplate和StringRedisTemplate Spring Boot&#xff08;十九&#xff09;…...

【Nodebb系列】Nodebb笔记写入方案

NodeBB写入方案 前言 最近在整理以前记录的碎片笔记&#xff0c;想把它们汇总到NodeBB中&#xff0c;方便管理和浏览。但是笔记内容有点多&#xff0c;并且用发帖的形式写到NodeBB中会丢失时间信息&#xff0c;因此整理了一套NodeBB写入方案&#xff0c;大致流程如下&#xf…...

计算机视觉——基于YOLOV8 的人体姿态估计训练与推理

概述 自 Ultralytics 发布 YOLOV5 之后&#xff0c;YOLO 的应用方向和使用方式变得更加多样化且简单易用。从图像分类、目标检测、图像分割、目标跟踪到关键点检测&#xff0c;YOLO 几乎涵盖了计算机视觉的各个领域&#xff0c;似乎已经成为计算机视觉领域的“万能工具”。 Y…...

鸿蒙小案例---心情日记

效果演示 代码实现 import { router, window } from kit.ArkUIEntry Component struct Index {async aboutToAppear(): Promise<void> {let w await window.getLastWindow(getContext())w.setWindowSystemBarProperties({statusBarColor: #00C6C3,statusBarContentColo…...

力扣第206场周赛

周赛链接&#xff1a;竞赛 - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台​​​​​​ 1. 二进制矩阵中的特殊位置 给定一个 m x n 的二进制矩阵 mat&#xff0c;返回矩阵 mat 中特殊位置的数量。 如果位置 (i, j) 满足 mat[i][j] 1 并且行 i 与列 j 中…...