C/C++|Pimpl Idiom(Pointer to IMPLementation) 指针实现模式浅析

Pimpl Idiom(Pointer to IMPLementation),也称为 “Opaque Pointer”(不透明指针)或 “Cheshire Cat”(柴郡猫)模式或者"指针实现模式"和"实现隐藏模式"。这种模式通过将类的实现细节放在一个单独的私有结构体中,并通过指针来访问,从而在不改变类接口的情况下,允许类的实现独立于类的定义进行修改和编译

Pimpl Idiom 的基本思想

Pimpl Idiom 的核心思想是将类的实现细节放在一个私有的实现类中,并使用指向该实现类的指针在公共接口类中进行引用。这种方式可以将类的实现细节完全隐藏在实现文件中,用户只需要看到公共接口。

实现步骤

  1. 定义公共接口类:在头文件中定义一个公共接口类,并在其中包含一个指向实现类的私有指针。
  2. 定义实现类:在源文件中定义实现类,包含类的实际实现细节。
  3. 在公共接口类的构造函数和析构函数中管理实现类的指针:在构造函数中创建实现类的实例,在析构函数中销毁它。

典型示例

头文件:Person.h

#ifndef PERSON_H
#define PERSON_H#include <string>class Person {
public:Person(const std::string& name, int age);~Person();std::string getName() const;int getAge() const;void setName(const std::string& name);void setAge(int age);private:class Impl;  // 前向声明实现类Impl* pImpl; // 指向实现类的指针
};#endif // PERSON_H

源文件:Person.cpp

#include "Person.h"
#include <iostream>// 定义实现类
class Person::Impl {
public:Impl(const std::string& name, int age) : name(name), age(age) {}std::string name;int age;
};//公共接口类的实现方法
Person::Person(const std::string& name, int age) : pImpl(new Impl(name, age)) {}Person::~Person() {delete pImpl;
}std::string Person::getName() const {return pImpl->name;
}int Person::getAge() const {return pImpl->age;
}void Person::setName(const std::string& name) {pImpl->name = name;
}void Person::setAge(int age) {pImpl->age = age;
}

使用示例:main.cpp

#include <iostream>
#include "Person.h"int main() {Person person("John Doe", 30);std::cout << "Name: " << person.getName() << ", Age: " << person.getAge() << std::endl;person.setName("Jane Doe");person.setAge(25);std::cout << "Name: " << person.getName() << ", Age: " << person.getAge() << std::endl;return 0;
}

从使用来看,用户仍然是无感的。

Pimpl Idiom 的优点

  1. 隐藏实现细节:用户只能看到头文件中的公共接口,无法看到实现细节。
  2. 减少编译依赖:头文件只包含指向实现类的指针,因此不需要包含实现类的头文件,从而减少编译依赖。
  3. 加快编译时间:由于头文件的变化不会影响依赖该头文件的其他文件,编译时间得到了显著加快。
  4. 二进制兼容性:由于实现类的变化不会影响公共接口类,二进制兼容性得到了保证。

Pimpl Idiom 的缺点

  1. 额外的内存分配和间接访问开销:由于使用了指针,存在额外的内存分配和间接访问的开销。
  2. 代码复杂性增加:需要定义和管理实现类和指针,代码复杂性有所增加。

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

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

相关文章

模板字符串

模板字符串&#xff08;Template Literals&#xff09;是在ES6&#xff08;ECMAScript 2015&#xff09;中引入的一种新的字符串表示法&#xff0c;它提供了构建字符串的更加强大和灵活的方式。模板字符串可以通过反引号&#xff08;&#xff09;&#xff08;而不是普通的单引号…

04-4.2.4 KMP 算法的进一步优化

&#x1f44b; Hi, I’m Beast Cheng&#x1f440; I’m interested in photography, hiking, landscape…&#x1f331; I’m currently learning python, javascript, kotlin…&#x1f4eb; How to reach me --> 458290771qq.com 喜欢《数据结构》部分笔记的小伙伴可以订…

IP分片的隐患,以及TCP分片

好的&#xff0c;我们来用一个生活中的例子更详细地解释 MTU、MSS&#xff0c;以及 IP 和 TCP 分片。 MTU 和 MSS 的概念 MTU&#xff08;Maximum Transmission Unit&#xff0c;最大传输单元&#xff09;&#xff1a; 假设你搬家&#xff0c;需要用卡车搬运家具。 卡车的最…

什么是动态联编、静态联编?

动态联编&#xff08;Dynamic Binding&#xff09;和静态联编&#xff08;Static Binding&#xff09;是面向对象编程中的两个重要概念&#xff0c;它们描述了程序在运行时如何确定调用哪个方法或属性。 静态联编&#xff08;Static Binding&#xff09; 静态联编&#xff0c…

Hadoop 2.0:主流开源云架构(一)

目录 一、引例&#xff08;一&#xff09;问题概述&#xff08;二&#xff09;常规解决方案&#xff08;三&#xff09;分布式下的解决方案&#xff08;四&#xff09;小结 自从云计算的概念被提出&#xff0c;不断地有IT厂商推出自己的云计算平台&#xff0c;但它们都是商业性…

Suno小技巧大揭秘,不会这些技巧别说你懂AI音乐

Suno是一个强大的AI音乐生成工具&#xff0c;它不仅可以帮你快速生成音乐&#xff0c;还能精确地根据你的需求进行调整。无论你是音乐小白还是专业音乐人&#xff0c;这篇文章将揭示一些鲜为人知的Suno技巧&#xff0c;帮助你最大化利用这个工具的潜力。 技巧一&#xff1a;精准…

解读下/etc/network/interfaces配置文件

/etc/network/interfaces 是一个常见的网络配置文件&#xff0c;通常在 Debian 及其衍生版本的 Linux 发行版中使用。该文件用于配置网络接口和网络连接参数&#xff0c;允许用户手动设置网络连接的属性&#xff0c;包括 IP 地址、子网掩码、网关、DNS 服务器等。 以下是一个可…

时间相关格式的转化

时间转秒越界 时间不加 L 就会越界 long l 90L * 24 * 60 * 60 * 1000;System.out.println(l);固定时间格式化 Date curTime new Date();SimpleDateFormat simpleDateFormat new SimpleDateFormat("HH:mm");// 19:30System.out.println(simpleDateFormat.format(…

POJ 2887:Big String ← 块状链表

【题目来源】http://poj.org/problem?id2887【题目描述】 You are given a string and supposed to do some string manipulations.【输入格式】 The first line of the input contains the initial string. You can assume that it is non-empty and its length does not exc…

基于JSP的班级同学录网站

你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术 工具&#xff1a;IDEA/Eclipse、Navicat、Maven 系统展示 首页 个人中心 同学录管…

Qt for android :解决requestperssion后无法马上访问设备的问题

描述 当需要访问到设备硬件时&#xff0c; 涉及到Android权限&#xff0c;所以需要进行权限申请&#xff0c; 申请完之后访问常常发现权限不足&#xff0c; 为什么呢&#xff1f; 1. 从Qt库角度看问题&#xff1a; 无论是 QCoreApplication::requestPermission [since 6.5] te…

确保数据一致性的技术

禁止其他人同时使用数据 互联网提供的服务是可以供大量用户同时访问的。此时&#xff0c;就要求即使多人同时引用同一数据&#xff0c;或者同时更新数据&#xff0c;也不会产生冲突并且可以顺利执行处理。这种处理方式被称为并发控制。 但是&#xff0c;如果多人同时操作同一数…

51单片机独立按键控制LED灯,按键按一次亮,再按一次灭

1、功能描述 独立按键控制LED灯&#xff0c;按键按一次亮&#xff0c;再按一次灭 2、实验原理 轻触按键:相当于是一种电子开关&#xff0c;按下时开关接通&#xff0c;松开时开关断开&#xff0c;实现原理是通过轻触按键内部的金属弹片受力弹动米实现接通和断开&#xff1b;…

网络网络层之(6)ICMPv6协议

网络网络层之(6)ICMPv6协议 Author: Once Day Date: 2024年6月2日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: 通信网络技术_Once-Day的博客-CS…

WPF-UI布局

WPF布局元素有如下几个&#xff1a; Grid&#xff1a;网格。可以自定义行和列并通过行列的数量、行高和列宽来调整控件的布局。StackPanel&#xff1a;栈式面板。可将包含的元素在竖直或水平方向上排成一条直线&#xff0c;当移除一个元素后&#xff0c;后面的元素会自动向前移…

怎么使用useLayoutEffect

useLayoutEffect 是 React 中的一个 Hook,与 useEffect 类似,但它在浏览器绘制任何内容之前同步触发。这意味着,如果你需要在 DOM 更新后执行某些操作,并且这些操作可能会影响到组件的布局或渲染,那么使用 useLayoutEffect 会更合适。 以下是如何使用 useLayoutEffect 的…

SpringAI(二)

大模型:具有大规模参数和复杂计算结构的机器学习模型.通常由深度神经网络构建而成,拥有数十亿甚至数千亿个参数.其设计目的在于提高模型的表达能力和预测性能,应对复杂的任务和数据. SpringAI是一个AI工程领域的应用程序框架 大概推出时间是2023年7月份(不确定) 目的是将S…

细说NLP中的Embedding层

文章目录 前言一、为什么要引入Embedding层二、Embedding层是怎么发挥作用的&#xff1f;三、感受Embedding的强大四、为什么理解Embedding的底层原理&#xff1f;总结 前言 在构建高效的自然语言处理模型时&#xff0c;Embedding层是不可或缺的组成部分。它不仅可以帮助我们捕…

WPF Frame应用 实现页面跳转

需求&#xff1a; 有一个F0View主页面入口&#xff0c;三个子页面&#xff08;First.xaml/Second.xaml/Third.xaml&#xff09;用Frame默认加载第一个页面 First.xaml。实现三个页面之间顺序跳转&#xff0c;并且每个页面只初始化一次。 实现&#xff1a; 1&#xff0c;将三…

Apache Kylin的入门

Apache Kylin入门教程 一、Apache Kylin简介 Apache Kylin是一个开源的分布式分析引擎&#xff0c;提供Hadoop之上的SQL接口及多维分析&#xff08;OLAP&#xff09;能力&#xff0c;以支持超大规模数据。最初由eBay Inc. 开发并贡献至开源社区&#xff0c;能够在亚秒内查询巨…