【问题标题】:Creating library using pimpl-idiom使用 pimpl-idiom 创建库
【发布时间】:2011-05-19 22:35:50
【问题描述】:

我正在尝试为将使用 pimpl-idiom 的库定义接口。下面是我定义的一个典型的接口类。

struct A {
public:
   void func1();
   void func2();
   virtual void notif1();
   virtual void notif2();
private:
   class AImpl;
   AImpl *impl;
}

函数func1()、func2()是接口函数。而notif1()、notif2()是应用程序必须实现的通知函数(在A的子类中)。

这是为库定义接口的正确方法吗? 这种方法有什么缺点还是有更好的解决办法?


感谢您的所有回答。 因此,从所有答案中,我收集到以下是表示库接口的好方法。

// Forward declaration
class AImpl;

struct A {
public:
   void func1();
   void func2();
private:
   virtual void notif1();
   virtual void notif2();
   AImpl *impl;
}

接口库将实现接口函数,应用程序将在派生类中实现通知函数。 有没有遵循这种模式的库的好例子?

【问题讨论】:

  • 与 pimpls 无关(即,与您的实际问题),但公共虚函数是个坏主意。 Herb Sutter 在他的“Exceptional C++”系列丛书中多次详细介绍了这一点。

标签: c++ pimpl-idiom


【解决方案1】:
  • pimpl 意味着您的类不能再仅是标题。这意味着对于库的用户来说,#include 标题已经不够了,他们还必须链接到库的目标代码。
  • 标头中类的运行时性能会稍微慢一些,因为它需要为每次访问不透明成员时取消引用一个指针。作为交换,该成语允许您更频繁地更改类的不透明成员。但这对于生产环境中的库来说并没有多大优势,因为无论如何它都不应该有太大变化。

我不认为这是个好主意。

【讨论】:

  • Here 是一篇关于使用 PIMPL 与声明纯虚拟类的好帖子
【解决方案2】:

你不需要在 struct A 中声明 AImpl 类。

我一般做一个前向声明:

//Forward Declaraion.
class AImpl;

struct A {
public:
   void func1();
   void func2();
   virtual void notif1();
   virtual void notif2();
private:
   AImpl *impl;
}

【讨论】:

    猜你喜欢
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    • 2019-01-19
    • 2015-07-16
    相关资源
    最近更新 更多