PIMPL 习惯用法真的在实践中使用吗?

2024-01-10

我正在看书“卓越的 C++”Herb Sutter 所著,在那本书中我了解了 PIMPL 习惯用法。基本上,这个想法是创建一个结构private的对象class并将它们动态分配给减少编译时间(并且还以更好的方式隐藏私有实现)。

例如:

class X
{
private:
  C c;
  D d;
} ;

可以改为:

class X
{
private:
  struct XImpl;
  XImpl* pImpl;
};

并且,在 .cpp 文件中定义:

struct X::XImpl
{
  C c;
  D d;
};

这看起来相当有趣,但我以前从未见过这种做法,无论是在我工作过的公司中,还是在我见过源代码的开源项目中。所以,我想知道这种技术是否真的用于实践。

我应该在任何地方使用它还是谨慎使用?这种技术是否建议用于嵌入式系统(其中性能非常重要)?


那么,我想知道这种技术真的在实践中得到应用吗?我应该在任何地方使用它还是谨慎使用?

当然是用的。我在我的项目中,几乎在每堂课上都使用它。


使用 PIMPL 习惯用法的原因:

二进制兼容性

当您开发库时,您可以添加/修改字段XImpl不会破坏与客户端的二进制兼容性(这意味着崩溃!)。由于二进制布局X当您添加新字段时,类不会改变Ximpl类,在次要版本更新中向库添加新功能是安全的。

当然,你也可以添加新的公共/私有非虚拟方法X/XImpl不会破坏二进制兼容性,但这与标准标头/实现技术相当。

数据隐藏

如果您正在开发一个库,尤其是一个专有库,那么最好不要透露使用了哪些其他库/实现技术来实现您的库的公共接口。要么是因为知识产权问题,要么是因为您认为用户可能会对实现做出危险的假设,或者只是通过使用可怕的转换技巧来破坏封装。 PIMPL 解决/缓解了这个问题。

编译时间

编译时间减少,因为只有源(实现)文件X当您添加/删除字段和/或方法时需要重建XImpl类(映射到在标准技术中添加私有字段/方法)。实际上,这是一个常见的操作。

使用标准标头/实现技术(无 PIMPL),当您向X,每个分配过的客户X(无论是在堆栈上,还是在堆上)需要重新编译,因为它必须调整分配的大小。好吧,每个不分配 X 的客户端also需要重新编译,但这只是开销(客户端的结果代码将是相同的)。

更重要的是,通过标准头文件/实现分离XClient1.cpp即使是私有方法也需要重新编译X::foo()被添加到X and X.h改变了,尽管XClient1.cpp由于封装原因不可能调用此方法!如上所述,它是纯粹的开销,并且与现实生活中的 C++ 构建系统的工作方式有关。

当然,当您只修改方法的实现时,不需要重新编译(因为您没有触及标头),但这与标准标头/实现技术相同。


是否建议在嵌入式系统(性能非常重要)中使用该技术?

这取决于你的目标有多强大。然而,这个问题的唯一答案是:衡量和评估你的所得和失去。另外,请考虑到,如果您不发布供客户在嵌入式系统中使用的库,则只有编译时间优势适用!

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

PIMPL 习惯用法真的在实践中使用吗? 的相关文章

随机推荐

  • PHP 数组...空括号的含义是什么?

    我遇到了一些示例代码 如下所示 form submit annotate admin settings submit 为什么 submit 后面有一个空的括号 里面什么都没有 这意味着什么 谁能给我举个例子吗 通常 根据我的理解 这可能是错
  • 双递归定义列表的双无限列表

    Context 我问的是修补递归定义的列表 https stackoverflow com q 53988970 12274另一天 我现在尝试通过在 2D 列表 列表的列表 上操作来将其提升一个级别 我将使用帕斯卡三角形作为示例 例如这个美
  • 如何在字符串中找到匹配的大括号对?

    假设我有一个字符串 付费 8个工作时间 公司规则 现在我想检查这个完整的字符串是否用括号括起来 基本上我想检查字符串是否是这样的 付费 8个工作时间 公司规则 如果它已经用括号括起来 那么我将保留它原样 否则我会将括号应用于完整的字符串 以
  • 如何从多行文本框中获取换行?

    在我的 windows forms C 应用程序中 我有一个 WordWrap true 的多行文本框 将 Text 属性设置为长字符串后 我需要获取通过换行生成的所有行 它与 Lines 属性不同 因为我的文本不包含换行符 我已经找到了使
  • 在启用自动筛选器且数据位于“要复制的行”的情况下,将一行复制并添加到工作表的末尾

    更新 替代解决方案不幸的是 我的问题没有答案 我需要继续该项目 我查看了之前编写的一些代码并决定使用它 我发现的解决方案不如用户 djbrett 建议的解决方案优雅 但它有效 我添加了一行额外的行 宏可以从中继续计数 有兴趣的可以看下面的代
  • 如何记录基于函数的视图参数?

    我正在使用 Django 1 11 和 Django REST Framework 3 7 开发 REST API 我安装了Django REST 招摇 https github com marcgibbons django rest sw
  • Clojure 实现可以快速启动吗?

    time java jar clojure 1 4 0 jar e println Hello world Hello world real 0m4 586s time python clojure py c py print Hello
  • 错误:tensorboard 2.0.2 要求 setuptools>=41.0.0,但您将拥有不兼容的 setuptools 40.6.2

    安装的时候出现这个错误 这会引起问题吗 错误 tensorboard 2 0 2 要求 setuptools gt 41 0 0 但您将拥有不兼容的 setuptools 40 6 2 我刚刚做了一个pip install setuptoo
  • 持久图形 WinForms

    我有一个 WinForms 应用程序 我必须在控件之间画一些线 这些行需要持久存在 所以我覆盖了表单OnPaint event 问题是 重新绘制的线条不是很平滑 我正在创建图形如下 Graphics g g this CreateGraph
  • 警告来源未知:“找不到虚拟表的链接器符号...”

    几天以来 我在调试时收到一条警告消息 我找不到它来自哪里 我已经在谷歌搜索并发现类似的东西 因为我有一个静态变量 但取出来并不能改变什么 这是main method int main int argc char argv if argc 2
  • 如何列出连接字符串列表的所有可能方法

    我想列出连接字符串列表的所有可能方法 例如 Input strings hat bag cab Output concatenated hatbag hatcab hatbagcab hatcabbag baghat bagcab bagh
  • 使用 JS 切换/显示一个定义的 DIV

    我有一把小提琴给你 http jsfiddle net vSs4f http jsfiddle net vSs4f 我想展示div sub menu只需点击一下a haschildren 如果身体加载div sub menu应该关闭 如果我
  • 将 VS2010 类图导出到 Visio

    我正在使用 VS2010 创建类图 有什么方法可以导入 VS2010 生成的类图以导入到 MS Visio 中吗 右键单击 Visual Studio 中的类图 然后选择 将图导出为图像 Choose 增强型图元文件格式 emf Visio
  • Spring Integration 中的 REST 端点使消息通道成为多线程

    我有一个非常简单的 Spring Boot 应用程序 它提供了几个静态端点 这应该驱动将 sftp 文件上传到 sftp 服务器 我的要求是 如果有多个文件 则文件应该排队 我希望通过 sftp spring 集成工作流程的默认行为来实现这
  • 使用 DOMXPath 保留

    标签内的换行符?

    我目前正在使用 PHP 和DOMXPath获取所有的内容 p 网页的元素 p
  • 如何过滤 SCons Glob 结果?

    我有时想从 SCons 的 Glob 结果中排除某些源文件 通常是因为我想用不同的选项编译该源文件 像这样的事情 objs env Object Glob cc objs env Object SpeciallyTreatedFile cc
  • 如何在不更改图像的情况下更新ALAsset的exif?

    I use setImageData metadata completionBlock of ALAsset更新资产的 exif 元数据 我只想更新元数据 但此方法需要imageData作为第一个参数 我使用下面的代码来生成imageDat
  • jQuery.event.props 未定义

    我在用着jquery event move https github com stephband jquery event move在触摸设备上创建移动事件 该脚本在第 580 行抛出错误 570 Make jQuery copy touc
  • 地理定位在设备 ionic3 中不起作用

    我正在从事 ionic 3 基于位置的工作 我无法在这里获取当前位置的纬度和经度 我提到了我的可用代码 它在浏览器级别工作正常 但在移动设备中无法工作 code ionic cordova plugin add cordova plugin
  • PIMPL 习惯用法真的在实践中使用吗?

    我正在看书 卓越的 C Herb Sutter 所著 在那本书中我了解了 PIMPL 习惯用法 基本上 这个想法是创建一个结构private的对象class并将它们动态分配给减少编译时间 并且还以更好的方式隐藏私有实现 例如 class X