何时在 C++ 中的嵌套类上使用 Pimpl 模式,反之亦然?
Posted
技术标签:
【中文标题】何时在 C++ 中的嵌套类上使用 Pimpl 模式,反之亦然?【英文标题】:When to use Pimpl pattern over Nested class in C++ or vice versa? 【发布时间】:2019-08-01 10:05:23 【问题描述】:在 C++ 中,大多数开发人员都使用 pimpl idiom 或 opaque pointers 对公共 API 隐藏私有数据/实现,例如:
-
=> 第一种情况 ## 不透明指针和 PIMPL 成语 ##
//在头文件中
class Node;
class Graph
public:
A();
private:
Node* m_nodeImpl;
// 类节点将在各自的cpp中定义
2。 =>第二种情况##内部类/嵌套类方法##
//在头文件中
class Graph
public:
Graph();
private:
class Node
// implementation goes here
Node* m_nodeImpl;
问题是...
-
从类设计的角度来看,这两者之间的实际区别是什么(可能是设计模式)?
每种方法的优缺点是什么?
【问题讨论】:
您可以将两者结合起来,您只需声明Graph::Node
类,并在源文件中定义。
至于区别,在第二个示例中,人类阅读头文件可以看到Node
类的详细信息。
@Someprogrammerdude 我认为这是 pimpl/opaque_ptr 相对于嵌套类 impl 的主要优势,对吧? (甚至隐藏细节)
通常这不是“隐藏”人类的问题,而是依赖问题。 IE。如果Node
的实现(和声明)取决于其他一些类,则需要将其包含在标题中。在 PIML 情况下,您不需要这个。这对于例如不需要公开实现细节的 API 类来说可能很重要。
@sklott 是的,我忘记了这一点,感谢您再次引起我的注意,是的,因此考虑到这两个因素,pimpl 是首选,对吧?那么实际上何时在 C++ 中使用内部类?除了人类可读的东西
【参考方案1】:
你混淆了几件事:
第一个例子
Type: opaque - 这意味着类型 name 对该标头的用户可见,但定义是隐藏的。
当您想与用户共享指针时,不透明类型特别有用,而不是它指向 的详细信息(或者阻止用户摆弄它,或者打破依赖关系)。
存储:粉刺。这只是意味着用户知道您(可能)在某处有一个 opaque 类型的实例,并且他们知道您的***对象的大小包括该指针。
第二个例子
类型:嵌套 - 这样可以避免污染封闭的命名空间(因此在您的程序的同一命名空间中可以有其他类型的 Node
,与第一个示例不同)但会暴露所有细节。
请注意,您的嵌套类型也可以前向声明,以控制可见性和命名空间污染。
存储:丢失。你是不是也想在这里有一个Node *m_impl
?否则,这些示例无法直接进行比较,因为您的 Graph
无处可保留 Node
,但是声明了类型。
【讨论】:
感谢您的简短而清晰的描述,Totally forgot to add Node impl ptr on 2nd example
,我明白了您的意思。以上是关于何时在 C++ 中的嵌套类上使用 Pimpl 模式,反之亦然?的主要内容,如果未能解决你的问题,请参考以下文章