Реализация pImpl с минимальным объемом кода

Какие приемы могут использоваться для уменьшения рабочей нагрузки реализации pImpl классы?

Заголовок:

class Foo {
    struct Impl;
    boost::scoped_ptr<Impl> self;
public:
    Foo(int arg);
    ~Foo();
    // Public member functions go here
};

Реализация:

struct Foo::Impl {
    Impl(int arg): something(arg) {}
    // All data members and private functions go here
};

Foo::Foo(int arg): self(new Impl(arg)) {}
Foo::~Foo() {}

// Foo's public functions go here (and they refer to data as self->something)

Как Вы улучшили бы это, с помощью Повышения, возможно наследования, CRTP или других приемов к предотвращению такого количества шаблонного кода, как возможно? Производительность во время выполнения не является проблемой.

10
задан Tronic 1 March 2010 в 03:57
поделиться

2 ответа

Реализация pimpl от Loki может быть хорошим ответом. См. Также статью DDJ по этому поводу.

5
ответ дан 4 December 2019 в 03:16
поделиться

Это возможно, но наивная реализация - это не то, что вам нужно.

Проблема в том, что шаблоны обычно встроены, наивная реализация была бы такой:

template <class Object>
class Pimpl
{
public:
  explicit Pimpl(Object* obj): mObject(obj) {}
  ~Pimpl() { delete mObject; }

  // either deep copy or no copy
private:
  Object* mObject;
};

Теперь проблема в том, что вы не хотите, чтобы Object был известен в вашем файле заголовка в целом (не для двоичная совместимость, но для управления зависимостями). И если Объект неизвестен, то вы не можете напрямую реализовать Деструктор , Конструктор копирования и Оператор присваивания ...

Однако проблема далеко не неразрешима! Boost действительно решил эту проблему для shared_ptr .

Идея состоит в том, чтобы передать второй элемент в конструктор, который позаботится об освобождении памяти первого и будет обеспечен хорошей реализацией по умолчанию.

Конечно, это работает косвенно.

namespace detail {
  template <class Object>
  struct Deleter { virtual void do(Object*) = 0; };
}

template <class Object>
class Pimpl
{
public:
  typedef detail::Deleter<Object> deleter_type;
  typedef boost::shared_ptr<deleter_type> deleter_pointer;

  Pimpl(std::auto_ptr<Object> obj, deleter_pointer del);
  ~Pimpl();
  Pimpl(const Pimpl&);
  Pimpl& operator(const Pimpl&);

private:
  Object* mObject;
  deleter_pointer mDeleter;
};

Это классическая идиома C ++, добавьте еще один уровень косвенности :)

1
ответ дан 4 December 2019 в 03:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: