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

Qt 中的 d-pointer 与 p-pointer小结

Qt 中的 d-pointer 与 p-pointer:

PIMPL 惯用法解析
在 Qt 库中,尤其是在其核心类和模块中,广泛使用了 PIMPL (Pointer to IMPLementation,指向实现的指针) 的编程惯用法。这种模式通过一对指针来实现:d-pointer (d_ptr) 和 p-pointer (q_ptr)。
1. PIMPL (Pointer to IMPLementation) 惯用法
目的: 将类的公共接口与其私有实现细节分离开来。
主要优点:
(1)减少编译依赖: 公共类的头文件只需要包含私有实现类的前向声明,而无需包含其完整的定义以及私有实现所依赖的其他头文件。当私有实现发生变化时,只需要重新编译私有实现文件,而包含公共类头文件的其他源文件无需重新编译,显著减少了大型项目的编译时间。
(2)隐藏实现细节: 提高了类的封装性,用户只能看到公共接口,无法直接访问私有成员。
(3)ABI 兼容性: 在不改变公共类布局(即其成员变量的内存偏移和大小)的情况下,可以修改私有实现类的内部结构。这对于构建二进制兼容的库非常重要,允许库的维护者在不强制用户重新编译使用该库的所有代码的情况下发布更新。
2. d-pointer (数据指针)
定义: 通常是公共类中的一个指针成员(在 Qt 中通常命名为 d_ptr),它指向一个包含所有私有成员和私有函数的单独的类(私有实现类)。
作用: 公共类通过 d_ptr 来访问和调用私有实现类中的实际逻辑和数据。它是从公共接口到私有实现的桥梁。
声明: 在 Qt 中,使用 Q_DECLARE_PRIVATE(ClassName) 宏在公共类的头文件中声明 d-pointer,并完成私有实现类的必要前向声明。
示例 (简化概念):

    // MyClass.h (公共接口)class MyClassPrivate; // 前向声明私有实现类class MyClass {// ... 公共成员和函数 ...private:MyClassPrivate* d_ptr; // d-pointer 指向私有实现Q_DECLARE_PRIVATE(MyClass) // Qt 宏,声明 d-pointer};// MyClass_p.h (私有实现 - 通常不对外公开)#include "MyClass.h" // 需要包含公共类头文件class MyClassPrivate {// ... 私有数据成员 ...// ... 私有实现函数 ...MyClass* q_ptr; // p-pointer 指回公共类Q_DECLARE_PUBLIC(MyClass) // Qt 宏,声明 q_ptr};// MyClass.cpp (实现文件)#include "MyClass_p.h" // 包含私有实现头文件// ... MyClass 公共函数的实现,通过 d_ptr 访问私有实现 ...

3. p-pointer (公共指针)
定义: 通常是私有实现类中的一个指针成员(在 Qt 中通常命名为 q_ptr),它指回创建该私有实现对象的那个公共类实例。
作用: 允许私有实现类中的代码方便地调用公共类中的公共(或保护)函数,或者访问公共(或保护)成员。它是从私有实现到公共接口的桥梁。
声明: 在 Qt 中,使用 Q_DECLARE_PUBLIC(ClassName) 宏在私有实现类的头文件中声明 p-pointer。
示例 (承接上文,简化概念):

    // MyClass.cpp (实现文件)#include "MyClass_p.h"// 私有实现函数示例void MyClassPrivate::somePrivateFunction() {Q_UNUSED(d_ptr); // 在私有实现中很少直接用 d_ptr// 通过 q_ptr 调用公共类的方法q_ptr->somePublicMethod();}// ... 公共函数的实现 ...

d-pointer 与 p-pointer 的核心区别与联系

特性d-pointer (d_ptr)p-pointer (q_ptr)
方向公共类 -> 私有实现类私有实现类 -> 公共类
所在类公共类 (Public Class)私有实现类 (Private Implementation Class)
主要作用隐藏实现细节,减少编译依赖,实现 PIMPL允许私有实现访问其对应的公共接口
声明宏Q_DECLARE_PRIVATE(ClassName)Q_DECLARE_PUBLIC(ClassName)
它们通常是成对出现的。d-pointer 建立了从公共接口到隐藏实现的连接,而 p-pointer 则提供了从实现返回到公共接口的便利途径,使得私有实现能够方便地与公共类进行交互。
总结
d-pointer 和 p-pointer 是 Qt 实现 PIMPL 惯用法的重要组成部分。d-pointer 负责将私有实现隐藏起来以优化编译时间和维护 ABI 兼容性,而 p-pointer 则为私有实现提供了访问其对应公共类的能力。理解这对指针对于深入理解 Qt 类的内部工作机制非常有帮助。

相关文章:

Qt 中的 d-pointer 与 p-pointer小结

Qt 中的 d-pointer 与 p-pointer: PIMPL 惯用法解析 在 Qt 库中,尤其是在其核心类和模块中,广泛使用了 PIMPL (Pointer to IMPLementation,指向实现的指针) 的编程惯用法。这种模式通过一对指针来实现:d-pointer (d_p…...

冷库耗电高的一种重要原因分析,以及一种降低冷库电费≥20%的方法

1.冷库耗电高的原因分析 1.1化霜不及时 固定周期化霜:传统定时化霜模式(如每日2次)未考虑实际结霜量,导致无效化霜(霜层薄时仍启动化霜),浪费大量电能。 化霜时间过长:化霜加热器…...

理解 Redis 事务-21(使用事务实现原子操)

使用事务实现原子操作 Redis 事务是一种在单个步骤中执行一组命令的机制。"要么全部,要么全部不"的方法确保了数据的一致性和完整性,尤其是在需要对相关数据进行多个操作时。没有事务,并发操作可能会导致竞争条件和不一致的数据状…...

神经网络加上注意力机制,精度反而下降,为什么会这样呢?注意力机制的本质是什么?如何正确使用注意力机制?注意力机制 | 深度学习

在深度学习的发展中,注意力机制的引入曾被誉为一次划时代的技术飞跃。无论是在自然语言处理领域产生Transformer架构,还是在图像识别、语音识别和推荐系统等多个方向取得显著成效,注意力机制的价值似乎毋庸置疑。然而,在一些实际应用场景中,研究人员和工程师却发现:在传统…...

触控精灵 ADB运行模式填写电脑端IP教程

•ADB模式,如果你手机已经root则可以直接运行,无需安装电脑端。 •ADB模式,如果你手机没有root,那你可以windows电脑下载【极限投屏】软件,然后你的手机和电脑的网络要同一个wifi,然后把你电脑的ip地址填写…...

uniapp|实现多端图片上传、拍照上传自定义插入水印内容及拖拽自定义水印位置,实现水印相机、图片下载保存等功能

本文以基础视角,详细讲解如何在uni-app中实现图片上传→水印动态编辑→图片下载的全流程功能。 目录 引言应用场景分析(社交媒体、内容保护、企业素材管理等)uniapp跨平台开发优势核心功能实现​图片上传模块多来源支持:相册选择(`uni.chooseImage`)与拍照(`sourceType:…...

linux有效裁剪视频的方式(基于ffmpeg,不改变分辨率,帧率,视频质量,不需要三方软件)

就是在Linux上使用OBS Studio录制一个讲座或者其他视频,可能总有些时候会多录制一段时间,但是如果使用剪映或者PR这样的工具在导出的时候总需要烦恼导出的格式和参数,比如剪映就不支持mkv格式的导出,导出成mp4格式的视频就会变得很…...

服务器密码安全运维解决新思路:凭据管理SMS+双因素SLA认证结合的方案

引言:云服务器安全成本困局 在云计算渗透率突破60%的今天,中小企业正面临严峻的安全悖论:某权威机构数据显示,72%的云上数据泄露事件源于凭据管理不当,而传统安全解决方案的采购成本往往超过中小企业年利润的8%。这种…...

论文阅读笔记——In-Context Edit

ICEdit 论文阅读笔记 指令图像编辑现有方法的局限: 微调类方法(InstructPix2Pix、Emu Edit、 Ultra Edit):需要大规模数据和算力、精度高但效率低且泛化性低;免训练方法(Prompt-to-Prompt、 StableFlow&am…...

Debian 系统 Python 开发全解析:从环境搭建到项目实战

Debian 系统 Python 开发全解析:从环境搭建到项目实战 在当今数字化时代,Python 凭借其简洁易读的语法和强大的功能,成为了最受欢迎的编程语言之一。Debian 作为一款稳定、安全且开源的 Linux 操作系统,为 Python 开发提供了理想的环境。本文将详细介绍在 Debian 系统上进…...

Next.js 15 与 Apollo Client 的现代集成及性能优化

Next.js 15 与 Apollo Client 的现代集成及性能优化 目录 技术演进集成实践性能优化应用案例未来趋势 技术演进 Next.js 15 核心特性对开发模式的革新 Next.js 15 通过引入 App Router、服务器组件(Server Components)和客户端组件(Clie…...

【后端高阶面经:MongoDB篇】41、MongoDB 是怎么做到高可用的?

一、MongoDB高可用核心架构:副本集(Replica Set)设计 (一)副本集角色与拓扑结构 1. 三大核心角色 角色职责描述资源占用选举权重数据存储Primary唯一接收写请求的节点,将操作日志(Oplog&…...

IO Vs NIO

一、IO(传统阻塞式) 全称‌:Input/Output(输入/输出) 定义‌:Java 1.0 引入的基础 I/O 模型,基于流(Stream)的同步阻塞操作,线程在读写数据时会阻塞直到操作完成。 二、NIO(新式非阻塞式) ‌全…...

offset 家族和 client 家族

在前端开发中,offset 家族和 client 家族是用于获取元素尺寸和位置的重要属性集合。以下是对这两个家族相关知识点的系统总结: 一、offset 家族 核心属性 offsetWidth / offsetHeight 含义:元素的总尺寸,包含内容区、内边距、边…...

DMBOK对比知识点整理(4)

1.常见数据质量维度 常见数据质量维度(DMBOK-P353)质量维度...

day12 leetcode-hot100-21(矩阵4)

240. 搜索二维矩阵 II - 力扣(LeetCode) 1.暴力法O(m*n) 思路:两层for循环即可。 2.二分查找O(m*logn) 思路:每行都用二分查找,因为每行都是排好序的 class Solution {public boolean searchMatrix(int[][] matrix, int targe…...

Java基础 Day24

一、进程和线程 1、进程 (1)概念 进程 (Process) 是计算机中的程序关于某数据集合上的一次运行活动 是系统进行资源分配的基本单位 简单理解:程序的执行过程(正在运行的应用程序) (2)特性…...

提问:鲜羊奶是解决育儿Bug的补丁吗?

在育儿这个"系统工程"中,过度提醒就像冗余代码:"快写作业"(重复调用)、"多穿衣服"(异常捕获)、"别玩手机"(进程阻断)。羊大师技术育儿实验…...

关于数据仓库、数据湖、数据平台、数据中台和湖仓一体的概念和区别

我们谈论数据中台之前, 我们也听到过数据平台、数据仓库、数据湖、湖仓一体的相关概念,它们都与数据有关系,但他们和数据中台有什么样的区别, 下面我们将围绕数据平台、数据仓库、数据湖和数据中台的区别进行介绍。 一、相关概念…...

Hive 分桶(Bucketing)深度解析:原理、实战与核心概念对比

一、分桶的意义:比分区更细的粒度管理 1.1 解决分区数据不均匀问题 分区的局限性:分区基于表外字段(如时间字段)划分数据,但可能导致部分分区数据量过大,部分过小,无法进一步细化。 分桶的定…...

网络协议DHCP

DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)是一种网络协议,用于自动给网络中的设备分配 IP 地址、子网掩码、默认网关、DNS 服务器等网络配置参数。 ✅ 一、DHCP 的作用 自动为客户端分配网络信息,…...

什么是可重组机器人?

可重组机器人是一种具有高度灵活性和适应性的新型机器人系统,能够根据不同任务需求,快速改变自身结构和功能。下面我从概念、结构、特点、应用领域、发展趋势等方面,为你详细介绍: 概念:可重组机器人是由多个标准化、模…...

4、docker compose

1、介绍 Docker Compose 是 Docker 官方提供的容器编排工具,用于简化多容器应用的开发、部署和管理。它通过声明式配置文件(YAML格式)定义容器化应用的服务、网络、存储等组件及其依赖关系,使用户能够通过单一命令快速启动、停止…...

Node.js全局对象详解:console、process与核心功能

在Node.js开发中,全局对象是一类无需引入即可直接访问的对象,它们为开发者提供了与运行时环境、系统交互和调试相关的核心功能。本文将深入解析Node.js中两个最常用的全局对象 console 和 process,并简要介绍其他全局对象的作用。通过代码示例…...

测试策略:AI模型接口的单元测试与稳定性测试

测试策略:AI模型接口的单元测试与稳定性测试 在构建支持AI能力的系统中,开发者不仅要关注业务逻辑的正确性,也必须保障AI模型接口在各种环境下都能稳定运行。这就要求我们在开发阶段制定清晰的测试策略,从功能验证到性能保障,逐步推进系统可用性、可维护性与可扩展性的提…...

SQL里几种JOIN连接

数据信息: 员工表EMP 部门表DEPT 一、INNER JOIN(内连接) 作用:只返回两个表中完全匹配的行,相当于取交集。 场景:查询「有部门的员工信息」。 示例: SELECT 员工.姓名, 部门.部门名称 FR…...

基于通义千问的儿童陪伴学习和成长的智能应用架构。

1.整体架构概览 我们的儿童聊天助手将采用典型的语音交互系统架构,结合大模型能力和外部知识库: 2. 技术方案分解 2.1. 前端应用/设备 选择: 移动App(iOS/Android)、Web应用,或者集成到智能音箱/平板等硬件设备中。技术栈: 移动App: React Native / Flutter (跨平台…...

生产环境Mysql推荐配置参数

以下是针对生产环境的 MySQL 配置(my.cnf 或 mysqld.cnf)推荐配置及说明。请根据实际硬件资源(如内存、CPU、磁盘类型)和应用场景调整参数。 核心配置模板(InnoDB 优化) [mysqld] #---------------------- 基础设置 ---------------------- datadir = /var/lib…...

LVS-DR 负载均衡群集

目录 一、LVS-DR集群 1、LVS-DR 工作原理 2、数据包流向分析 3、LVS-DR 模式特点 二、直接路由模式(LVS-DR) 1、准备案例环境 2、配置负载调度器(101) (1)配置虚拟IP 地址(VIP&#xff…...

理解并解决高丢包率问题,构建清晰流畅的实时音视频通话

丢包作为数字通信中的重要干扰因素,常常潜伏在表面之下,却严重影响性能,将清晰的对话变的模糊不清,将连贯的演示变的断断续续。因此,对音视频通话相关应用的开发者来说,理解丢包率非常重要。 什么是丢包&am…...