这两种 PIMPL 方法之间的差异
Differences between these two PIMPL approaches
因此,在尝试接触 PIMPL
习语时,我们发现了两种常见的做法:
在 class:
之外使用 前向声明
class PimplClass;
class VisibleClass
{
private:
PimplClass* d_ptr;
};
在 class:
中使用 前向声明
// *.hpp
class VisibleClass
{
private:
struct PimplClass;
PimplClass* d_ptr;
};
// *.cpp file:
struct VisibleClass::PimplClass
{
int x;
};
这里有两个问题:
- 老实说,我不知道为什么第二个有效。我的意思是表达式 struct PimplClass 我只从前向声明中知道,而不是在 class 中。有人可以给我解释一下吗?
- 使用哪种解决方案?优点在哪里还是只是品味问题?
这也是一个前向声明,但是 PimplClass
的范围在 VisibleClass
内。
第二种解决方案的优点是不会将内部类型转储到全局名称空间中。将 PimplClass
限制在 VisibleClass
内是完全合理的。
在这两种情况下,Pimpl 惯用法通常应使用 std::unique_ptr
将接口和 Impl 的生命周期联系在一起,而不是原始的拥有指针。
您可以在 class 范围内进行前向声明。所以第二个例子完全正确。
第二个例子的主要优点是你的 PimplClass
不能从任何地方访问,只能从 VisibleClass
访问,因为它是在 private 中声明的(前向声明的) 节。
因此,在尝试接触 PIMPL
习语时,我们发现了两种常见的做法:
在 class:
之外使用 前向声明class PimplClass; class VisibleClass { private: PimplClass* d_ptr; };
在 class:
中使用 前向声明// *.hpp class VisibleClass { private: struct PimplClass; PimplClass* d_ptr; }; // *.cpp file: struct VisibleClass::PimplClass { int x; };
这里有两个问题:
- 老实说,我不知道为什么第二个有效。我的意思是表达式 struct PimplClass 我只从前向声明中知道,而不是在 class 中。有人可以给我解释一下吗?
- 使用哪种解决方案?优点在哪里还是只是品味问题?
这也是一个前向声明,但是
PimplClass
的范围在VisibleClass
内。第二种解决方案的优点是不会将内部类型转储到全局名称空间中。将
PimplClass
限制在VisibleClass
内是完全合理的。
在这两种情况下,Pimpl 惯用法通常应使用 std::unique_ptr
将接口和 Impl 的生命周期联系在一起,而不是原始的拥有指针。
您可以在 class 范围内进行前向声明。所以第二个例子完全正确。
第二个例子的主要优点是你的 PimplClass
不能从任何地方访问,只能从 VisibleClass
访问,因为它是在 private 中声明的(前向声明的) 节。