Создание библиотеки с использованием pimpl-idiom - PullRequest
1 голос
/ 20 мая 2011

Я пытаюсь определить интерфейсы для библиотеки, которая будет использовать 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;
}

Библиотека интерфейса будет реализовывать функции интерфейса, а приложение будет реализовывать функции уведомления в производном классе.,Есть ли хороший пример библиотеки, которая следует этому шаблону?

Ответы [ 2 ]

3 голосов
/ 20 мая 2011
  • pimpl означает, что ваш класс больше не может быть только заголовком.Это означает, что для пользователей библиотеки уже недостаточно включить #include ваш заголовок, но они также должны ссылаться на объектный код библиотеки.
  • Производительность класса в заголовке во время выполнения будет несколько ниже, посколькуразыменовать указатель для каждого доступа непрозрачного члена.В обмен на это идиома позволяет вам чаще менять непрозрачных членов класса.Но это не является большим преимуществом для библиотеки в производстве, потому что тогда она все равно не должна сильно меняться.

Не думаю, что это хорошая идея.

1 голос
/ 20 мая 2011

Вы не обязаны объявлять класс AImpl внутри структуры A.

Обычно я делаю предварительное объявление:

//Forward Declaraion.
class AImpl;

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