考虑以下两种实现 pimpl 习语的方法:
// file g_visible.h
//global forward declarations
class HiddenStuff_A;
class HiddenStuff_B;
class g_visible
{
public:
// API goodies for the end-user
private:
std::unique_ptr< HiddenStuff_A > hs_a;
std::unique_ptr< HiddenStuff_B > hs_b;
}
和
// file p_visible.h
class p_visible
{
public:
// API goodies for the end-user
private:
// private forward declarations
class HiddenStuff_A;
class HiddenStuff_B;
std::unique_ptr< HiddenStuff_A > hs_a;
std::unique_ptr< HiddenStuff_B > hs_b;
}
问题:对于最终用户——即对于包含 [gp]_visible.h 文件之一的开发人员——包含 g_visible.h 或 p_visible 之间有什么区别.h?
最佳答案
不同之处在于它们在全局范围内有两个“隐藏”类的前向声明(或者如果您的代码将 g_visible
放在命名空间中,则无论碰巧是什么命名空间)。
不必要的 namespace 污染。实际后果:
- 他们不能在该命名空间中再次使用相同的标识符,而我倾向于对所有 pImpl 类使用
Impl
- 他们的 IDE 的完成列表在他们永远不想选择的标识符上浪费了空间。
- 客户端代码可以定义
HiddenStuff_A*
或 ``HiddenStuff_B&类型的变量或函数参数,但除非
g_visible提供工厂或
HiddenStuff_X` 的定义包含在翻译单元中,它实际上无法获取指向或调用的变量
简而言之,没有 Impl
声明 private
是一个糟糕的选择。
关于c++ - 针对 pimpl 的最终用户,pimpl 中的全局和私有(private)前向声明之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27031713/