pImpl习语在实践中是否真的被使用?

我正在阅读Herb Sutter的书“Exceptional C ++”,并且在那本书中我学习了pImpl习语。 基本上,这个想法是为一个classprivate对象创建一个结构并动态地分配它们来减少编译时间 (并且以更好的方式隐藏私有实现)。

例如:

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

可以更改为:

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

并在CPP中定义:

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

这看起来很有趣,但我从来没有见过这种方法,无论是在我工作的公司,还是在我看过源代码的开源项目中。 所以,我想知道这种技术在实践中真的被使用了吗?

我应该在任何地方或谨慎使用它吗? 这种技术是否推荐用于嵌入式系统(性能非常重要)?


所以,我想知道这种技术在实践中真的被使用了吗? 我应该在任何地方或谨慎使用它吗?

当然,在我的项目中,几乎每个班级都会使用它,原因如下:

  • 数据隐藏
  • 重新编译时间真的减少了,因为只有源文件需要重建,而不是头文件以及包含它的每个文件
  • 二进制兼容。 由于类声明不会更改,因此更新库是安全的(假设您正在创建库)
  • 这种技术是否推荐用于嵌入式系统(性能非常重要)?

    这取决于你的目标有多强大。 然而,这个问题的唯一答案是:衡量和评估你获得和失去的东西。


    似乎很多图书馆都使用它来保持它们的API稳定,至少对于某些版本。

    但至于所有的东西,你不应该在任何地方使用任何东西,不要小心。 在使用之前一定要考虑。 评估它给你带来的好处,以及它们是否值得你付出代价。

    它可能给你的好处是:

  • 有助于保持共享库的二进制兼容性
  • 隐藏某些内部细节
  • 减少重新编译周期
  • 这些对你来说可能是或可能不是真正的优势。 对我来说,我不在乎几分钟的重新编译时间。 终端用户通常也不会,因为他们总是从头开始编译一次。

    可能的缺点是(也在这里,取决于实施,以及它们是否对你来说是真正的缺点):

  • 由于更多的分配比使用天真的变体增加了内存使用量
  • 增加维护工作量(您必须至少编写转发功能)
  • 性能损失(编译器可能无法内联内容,因为它与您的类的幼稚实现一样)
  • 所以,小心地给每件事物一个价值,然后为自己评估一下。 对我来说,几乎总是发现使用pimpl习语是不值得的。 只有一个我个人使用它的情况(或者至少类似的情况):

    我的C ++包装的Linux stat调用。 这里来自C头的结构可能是不同的,这取决于设置了什么#defines 。 由于我的包装头无法控制它们,我只在我的.cxx文件中#include <sys/stat.h>并避免这些问题。


    同意所有其他人的货物,但让我证明一个限制: 不适用于模板

    原因是模板实例化需要在实例化发生的地方提供完整的声明。 (这就是您没有将模板方法定义到CPP文件中的主要原因)

    你仍然可以参考模板化的子类,但是由于你必须包含它们,编译时的“实现解耦”(避免包括所有平台特定的代码,缩短编译)的每个优点都会丢失。

    对于传统的OOP(基于继承)而言,这是一个很好的范例,但不适用于泛型编程(基于专业化)。

    链接地址: http://www.djcxy.com/p/40251.html

    上一篇: Is the pImpl idiom really used in practice?

    下一篇: Developing as a programmer