这两种 PIMPL 方法之间的差异

Differences between these two PIMPL approaches

因此,在尝试接触 PIMPL 习语时,我们发现了两种常见的做法:

  1. 在 class:

    之外使用 前向声明
    class PimplClass;
    class VisibleClass
    {
    private:
        PimplClass* d_ptr;
    };
    
  2. 在 class:

    中使用 前向声明
    // *.hpp
    class VisibleClass
    {
    private:
       struct PimplClass;
       PimplClass* d_ptr;       
    };
    // *.cpp file:
    struct VisibleClass::PimplClass
    {
      int x;
    };
    

这里有两个问题:

  • 这也是一个前向声明,但是 PimplClass 的范围在 VisibleClass 内。

  • 第二种解决方案的优点是不会将内部类型转储到全局名称空间中。将 PimplClass 限制在 VisibleClass 内是完全合理的。

在这两种情况下,Pimpl 惯用法通常应使用 std::unique_ptr 将接口和 Impl 的生命周期联系在一起,而不是原始的拥有指针。

您可以在 class 范围内进行前向声明。所以第二个例子完全正确。

第二个例子的主要优点是你的 PimplClass 不能从任何地方访问,只能从 VisibleClass 访问,因为它是在 private 中声明的(前向声明的) 节。