什么时候在 C++ 中使用 Pimpl 模式而不是 Nested class ,反之亦然?

When to use Pimpl pattern over Nested class in C++ or vice versa?

在 C++ 中,大多数开发人员使用 pimpl idiomopaque pointers 从 public API,例如:

  1. => 第一种情况 ## 不透明指针和 PIMPL 习语 ##

//在头文件中

class Node; 
class Graph {  
 public:    
  A();  
 private:  
  Node* m_nodeImpl; 
}

// class节点将在各自的cpp中定义

2。 => 第二种情况 ## 内部 class / 嵌套 class 方法 ##

//在头文件中

class Graph {  
 public:    
  Graph(){};  
 private:  
  class Node
  {
    // implementation goes here
  }
  Node* m_nodeImpl;
}

问题是...

  1. 从 class 设计(可能是设计模式)的角度来看,这两种方法之间的实际区别是什么?
  2. 各自的优点和缺点是什么?

你混淆了几件事:

  1. 第一个例子

    1. 类型:不透明 - 这意味着类型 name 对该 header 的用户可见,但定义是隐藏的。

      不透明类型在您想与用户共享指针时特别有用,但不想与用户共享指针所指向的内容的详细信息(要么阻止用户摆弄它,要么或打破依赖关系)。

    2. 存储:pimpl。这只是意味着用户知道您(可能)在某处有一个不透明类型的实例,并且他们知道您的 top-level object 的大小包括该指针。

  2. 第二个例子

    1. Type: nested - 这避免了污染封闭的命名空间(因此与第一个示例不同,在您的程序中的同一命名空间中可以有其他类型的 Node)但公开了所有详情。

      请注意,您的嵌套类型也可以是 forward-declared,以控制可见性和命名空间污染。

    2. 存储:丢失。你是不是也想在这里有一个Node *m_impl?否则这些示例不能直接比较,因为您的 Graph 没有地方可以保留 Node,但是类型已声明。