用c ++处理Body Idiom

时间:2012-09-28 10:49:22

标签: c++ design-patterns abstraction

我的库中有一个类,我想向用户公开。我不想暴露整个类,因为我可能希望稍后进行二进制兼容的更改。我对以下哪种方式最好感到困惑。

//case1:
struct Impl1;
struct Handle1
{
// The definition will not be inline and will be defined in a C file
// Showing here for simplicity
  void interface() 
  {
    static_cast<Impl1*>(this)->interface();
  }
}    
struct Impl1 : public Handle1
{
  void interface(){/*do Actual work*/}
  private:
  int _data;// and other private data
};

//case2:    
struct Impl2
struct Handle2
{
  //constructor/destructor to manage impl
  void interface() // will not be inline as above.
  {
    _impl->interface();
  }
  private:
  Impl2* _impl;
}

struct Impl2
{
  void interface(){/*do Actual work*/}
  private:
  int _data;// and other private data
};

Handle类仅用于公开功能。它们将仅在库内创建和管理。继承只是用于抽象实现细节。不会有多个/不同的impl类。在性能方面,我认为两者都是相同的。是吗?我正在考虑采用case1方法。是否有任何问题需要注意?

1 个答案:

答案 0 :(得分:2)

你的第二种方法看起来非常像编译防火墙 成语(有时被称为pimpl成语)。唯一的区别是 在编译防火墙的习语中,通常是实现类 (但并非总是)定义为成员。不要忘记构造函数 (分配Impl)和析构函数(释放它)。沿 使用复制构造函数和赋值运算符。

第一种方法也有效,但需要工厂功能 创建对象。当我使用它时,我只是制作了所有的 函数在Handle纯虚拟中,让客户端代码调用它们 直。在这种情况下,因为客户端代码实际上有指向您的指针 对象(在编译防火墙成语中,唯一​​的指针是在 Handle类本身),客户端将不得不担心内存 管理;如果没有可能的循环,这是一种情况 shared_ptr很有意义。 (工厂功能可以返回 例如,shared_ptr,客户端代码可能永远不会看到原始指针。)