这个pimpl替代品会牺牲什么?

时间:2014-06-21 21:14:25

标签: c++

不幸的是,我很多地使用Qt(它声称它不是很多东西),而且Qt广泛使用了pimpl成语,我得到了很多体验pimpl模式并学会了我不喜欢它。我喜欢使用的另一种选择是:

// .hpp file

struct A
{
private:
  struct B;
  int a{};
};

// .cpp file
struct A::B
{
  // replaces a private member function
  static void f(A& a)
  {
    ++a.a;
  }
};

但是使用这种方法牺牲了什么而不是使用私有函数成员或pimpl?性能,二进制兼容性?使用pimpl,我们知道它是性能,因为增加了间接的1级。

3 个答案:

答案 0 :(得分:0)

嗯,对于一个 - 如果struct B需要是一个采用任意类型参数的类template,这将无法奏效。

答案 1 :(得分:0)

pimpl的想法是在A的每个实例中存储数据,而不使A的公共接口的数据部分的内部结构。

您的代码没有这样做,因此它不会取代pimpl。

简而言之,您的代码是一种隐藏辅助函数的方法,这些函数是实现细节。 pimpl做到了这一点,并且隐藏了作为实现细节的辅助数据。

答案 2 :(得分:0)

如果A::B仅包含静态方法/数据,那么在标题中完全暴露它是没有意义的。您可以更简单地在.cpp文件中实现这些功能,而不会让它们成为该类的一部分。

// .hpp file

struct A
{
};

// .cpp file
void f(A& a)
{
  // some function
  // Might be called from the implementation of methods of `A`
}

因此,首先没有理由拥有嵌套类。

另一方面,如果A::B中的非静态数据/ ...需要与A的实例关联(其中使用了pimpl习语,然后你需要将A::B实例与A的每个实例相关联。

执行此操作的直接方法是在每个A::B中保存指向A的指针。这是pimpl习语。