【问题标题】:What is this design pattern? How to use it?这是什么设计模式?如何使用它?
【发布时间】:2012-01-31 20:26:16
【问题描述】:

假设我有这样的课程(简化):

class Foo_p;
class Foo
{
private:
  Foo_p *p;
public:
  Foo();
  /* methods, etc... */
};

这个类是 API 的一部分。 Foo_p 是类的所有私有部分,不是 像往常一样在类 Foo 中声明,而是在一个单独的前向声明的类中声明,该类仅由外部不可见的底层实现使用。

我已经在几个项目中看到过这种模式,它有名字吗?

另外,如何正确使用它(例如异常安全等)?实际实施应该去哪里?在 Foo 类中,像往常一样,只使用 Foo_p 来存储数据,还是在 Foo_p 类中,Foo 只是一个包装器?

【问题讨论】:

    标签: c++ oop design-patterns


    【解决方案1】:

    【讨论】:

    • @pmb 感谢您的提示。修复了所有三个链接。 o.O 永久链接...当他们工作时,他们非常好 :(
    【解决方案2】:

    这就是已知的 PIMPL。私有/指向私有的实现。类 Foo_p,您的类 would 已被私有实现并通过指向它的指针进行访问,因此他们不会向客户显示真正的类,他们只能看到您选择的公共接口揭露。它基本上从标题中抽象出 protectedprivate 成员中存在的实现细节的痕迹。

    我发现它在 VC++ 中很笨拙——它会破坏代码完成。如果您非常确定自己的实现并且不希望在标题中显示 privateprotected 成员,这将很有用。

    我将Foo_p类的实际实现放在Foo类的cpp文件中,虽然这可能是代码完成中断的原因,但至少我不必冒险通过包含其标头来重用类。

    【讨论】:

    • 标题和正常保护级别(公共/私有)是否都“基本上隐藏了实现”?
    • @Matthew:不幸的是,没有。您必须包含实现标头,当它们依赖于 Windows 标头时,它们通常会让人感到不舒服,这些标头非常糟糕。
    • @MatthewFlaschen:是的,但只是在你无法访问它的意义上,但在查看代码时你仍然可以看到它。
    • 对,Pubby 给我的维基百科引用帮助我理解了它,尤其是关于二进制兼容性的一点。
    • Afaik,protected 成员不会从 Foo 移动到 Foo_p,因为它们也是 API 的一部分。只有private 成员不是API 的一部分,所以它们对用户来说是隐藏的。
    【解决方案3】:

    它是一个 d-pointer,它是一种不透明指针。类似于 PIMPL 成语。

    C++ 类声明中常用的一种不透明指针是 d 指针。 d-pointer 是唯一的私有数据成员 类并指向结构的实例。由 Arnt Gulbrandsen 命名 奇趣科技,这种方法允许类声明省略私有 数据成员,除了 d 指针本身。 [6]结果是 更多类的实现隐藏在视图中,添加新的 私有结构的数据成员不影响二进制 兼容性,以及包含该类的头文件 声明只需要#include那些需要的其他文件 类接口,而不是它的实现。作为一方 好处,编译速度更快,因为头文件更改较少 经常。 Qt 和 KDE 库中大量使用 d 指针。

    https://en.wikipedia.org/wiki/Opaque_pointer#C.2B.2B

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-22
      • 1970-01-01
      相关资源
      最近更新 更多