为什么要使用“PIMPL”习惯用法? [复制]

2023-12-04

背景资料:

The PIMPL 习语(指向 IMPLementation 的指针)是一种实现隐藏技术,其中公共类包装了在公共类所属的库外部无法看到的结构或类。

这对库的用户隐藏了内部实现细节和数据。

在实现这个习惯用法时,为什么要将公共方法放在 pimpl 类上而不是公共类上,因为公共类方法实现将被编译到库中并且用户只有头文件?

为了说明这一点,这段代码将Purr()impl 类的实现并包装它。

为什么不直接在公共类上实现 Purr 呢?

// header file:
class Cat {
    private:
        class CatImpl;  // Not defined here
        CatImpl *cat_;  // Handle

    public:
        Cat();            // Constructor
        ~Cat();           // Destructor
        // Other operations...
        Purr();
};


// CPP file:
#include "cat.h"

class Cat::CatImpl {
    Purr();
...     // The actual implementation can be anything
};

Cat::Cat() {
    cat_ = new CatImpl;
}

Cat::~Cat() {
    delete cat_;
}

Cat::Purr(){ cat_->Purr(); }
CatImpl::Purr(){
   printf("purrrrrr");
}

我认为大多数人将其称为手柄本体成语。参见詹姆斯·科普林的书高级 C++ 编程风格和习惯用法。它也被称为柴郡猫因为刘易斯·卡罗尔的角色逐渐消失,直到只剩下笑容。

示例代码应分布在两组源文件中。那么只有Cat.h是产品附带的文件。

CatImpl.h包含在Cat.cpp and CatImpl.cpp包含实现CatImpl::咕噜声()。使用您的产品的公众不会看到这一点。

基本上,这个想法是尽可能隐藏实施过程,以免被窥探。

当您拥有作为一系列库提供的商业产品时,这非常有用,这些库可通过 API 进行访问,客户的代码将根据该 API 进行编译和链接。

我们通过重写来做到这一点IONA's Orbix3.3 2000年产品。

正如其他人所提到的,使用他的技术将实现与对象的接口完全解耦。然后你就不必重新编译所有使用的东西Cat如果你只是想改变的实现Purr().

该技术用于称为按合同设计.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么要使用“PIMPL”习惯用法? [复制] 的相关文章

随机推荐

  • 项目级别的 SourceSafe 合并

    我正在运行 SourceSafe 并且我的代码有两个分支 我目前正在使用手动方法运行报告来显示差异 然后手动将每个文件一一合并 不过 我正在尝试找到一种简化的方法来在项目级别上做到这一点 如果该过程一次显示每个文件一个就可以了 我只是担心如
  • 将逗号分隔值拆分到具有固定列数的目标表中

    我在 Postgres 13 1 数据库中有一个包含单列的表 它由许多带有逗号分隔值的行组成 最多大约 20 个元素 我想将数据分成多列 但我的列数有限 例如单行中有 5 个和 5 个以上的 CSV 值 因此多余的值必须转移到新的 下一行
  • React Native:firestore/firebase 预期 collection() 的第一个参数是 CollectionReference...怎么样?

    因此 我有一个简单的 React Native 应用程序 它是我使用 Expo 创建的 并在我的个人 Android 设备上进行调试 我已将 firebase firestore 包含到我的应用程序中 现在尝试在单击按钮时将对象添加到 fi
  • 将 web.config 文件转换为 .htaccess

    我正在寻找一种将 IIS 重写规则转换为 htaccess 文件的方法 我找不到任何工具来自动执行此操作 我所能得到的只是 500 个内部服务器错误 web config 文件如下所示
  • 添加“Authorization”标头会导致 Spring Security 保护允许的端点

    所以 我的里面有这个WebSecurityConfigurerAdapter public class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdap
  • 如果 C# 中的相同位置已存在文件,则始终创建新文件

    我使用下面的代码创建了一个新文件 但如果该文件已经存在 那么我需要使用另一个文件名创建一个新文件 这可能吗 FileStream fs new FileStream filePath FileMode Append FileAccess W
  • 带等高线的 Gnuplot 、 pm3d

    我正在用一些值绘制一个矩阵 3D 并且我需要向图中添加等高线 是否有一个简单的 gnuplot 命令可以做到这一点 我尝试了命令 设置轮廓基础 但只出现了 1 行 我认为应该有很多行 看matlab图片 当我在 gnuplot 中绘制它时
  • R flextable - 如何在合并单元格下添加表宽水平边框

    当合并单元格时 是否有一种聪明的方法可以使水平边框表格变宽 在下面的示例中 它还不是表宽 或者我应该编写一个函数来计算正确的索引 library flextable library officer library dplyr myft lt
  • MySQL 查询查找订购了两种特定产品的客户

    我无法提出一个查询来查找同时购买了 PROD1 和 PROD2 的所有客户 这是一个伪查询 看起来像我想要做的 显然这是行不通的 SELECT COUNT DISTINCT userid FROM TRANSACTIONS WHERE pr
  • javascript - 如何让对象返回一个不是对象本身的值

    当创建一个x new Date 对象 如果你把它放入console log x 将输出一个字符串 有没有办法制作一个自定义对象 该对象将返回一个不是对象本身的不同值 有一个函数可以做到这一点 toString 但是如果你这样做console
  • 为 CakePHP 发送正确的 JSON 内容类型

    在我的 CakePHP 应用程序中 我返回 JSON 并针对某些请求退出 例如 尝试通过 GET 请求访问 API 进行登录 header Content Type application json echo json encode arr
  • Intellij Idea 13 有代码片段编辑器吗?

    Visual Studio 有片段设计师扩展可用于创建和管理自定义代码片段 是否有类似 Intellij Idea 13 的扩展 或者简单添加自定义代码片段的方法 据我所知 没有扩展 而且我不熟悉 Snippet Designer 但 In
  • 将 Guid 表示为一组整数

    如果我想将 guid 表示为一组整数 我将如何处理转换 我正在考虑获取 guid 的字节数组表示形式并将其分解为可以转换回原始 guid 的尽可能少的 32 位整数 首选代码示例 另外 生成的整数数组的长度是多少 由于 GUID 只有 16
  • 安装Python geopandas失败

    我正在尝试安装 geopandas 进行以下设置 Windows 64 Anaconda2 64 位 Python 2 7 尝试过两件事 1 pip install geopandas 这给了我以下错误 WindowsError Error
  • 在Python中使用win32com.client如何查找和替换多个文本

    我正在尝试使用查找和替换来将多个字符串值添加到 Word 文档中win32com客户端Python 库 我可以查找并替换一个值 但我不知道如何对多个值执行此操作 这是我到目前为止所拥有的 import win32com client wor
  • 使用 UITextField + UIPickerview 时禁用键盘输入

    这个项目也是点击textfield pickerview打开 但是上面显示的数据可以在该部分中输入 我怎样才能将其关闭 所以请看下面我的选择 如果单击文本字段 我将打开选择器视图 import UIKit import NVActivity
  • NetworkX - 阻止节点聚集 - 尝试 Scale/K 参数

    我有大约 28 个节点 其中大多数节点之间都有边 有些是孤立的 没有边 孤立的节点分布得很好 但连接的节点却堆积得很厉害 我看不到任何东西 我尝试了各种 node sizes scale 和 k 参数 它总是给我 大致 相同的结果 有什么办
  • MATLAB 以不同方式随机排列列

    我有一个非常大的矩阵 A 有 N 行和 M 列 我基本上想做以下操作 for k 1 N A k A k randperm M end 但又快又高效 M 和 N 都非常大 这只是一个更大的外循环中的一个内循环 更多上下文 我正在尝试对相关矩
  • git 验证可信标签

    我想包括git tag v命令进入部署过程以捕获未签名的标签或由不可信的 GPG 密钥签名的标签 该命令返回退出代码为0如果标签具有有效签名 但不关心签名密钥是否可信 我不想手动 grep 结果 GPG 消息 我还没有尝试过 文档也没有提到
  • 为什么要使用“PIMPL”习惯用法? [复制]

    这个问题在这里已经有答案了 背景资料 The PIMPL 习语 指向 IMPLementation 的指针 是一种实现隐藏技术 其中公共类包装了在公共类所属的库外部无法看到的结构或类 这对库的用户隐藏了内部实现细节和数据 在实现这个习惯用法