用这种粉刺替代品能牺牲什么呢

what does one sacrifice with this pimpl alternative?

本文关键字:牺牲 什么 替代品      更新时间:2023-10-16

不幸的是,我经常使用Qt(它声称有很多东西实际上并不是),而且由于Qt广泛使用了粉刺习语,我也获得了很多关于粉刺模式的经验,并且知道我不喜欢它。我喜欢使用的另一种选择是:

// .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要牺牲什么呢?性能,二进制兼容性?对于粉刺,我们知道它是性能,因为增加了1级间接。

好吧,如果struct B需要是一个类template,接受任意类型参数,这将不起作用。

如果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中保存一个指向A::B的指针。这就是痘痘习语

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

你的代码没有这样做,所以它不能替换pimpl。

简而言之,你的代码是隐藏辅助函数的一种方式,它是实现细节。