Нераспространенный умный указатель с неполными типами - PullRequest
8 голосов
/ 30 января 2012

Существует ли стандартный класс указателя (или Boost), который является не общим указателем, который работает с неполными типами? Я ознакомился со стандартом C ++ 11 и библиотекой boost и не могу его найти, хотя он выглядит очень полезным типом.

Например, я хотел бы иметь возможность создавать непрозрачные типы, используя умный указатель.

  class A;
  wrap_ptr<A> some_func();
  void other_func( A const & );

A - непрозрачный тип, который может использоваться для различных функций. Пользователь вышеупомянутого интерфейса имеет только неполное определение A, но должен иметь возможность удалить / сбросить указатель. Я знаю, что вышеупомянутое может быть сделано с shared_ptr, но у него есть издержки, которые я не хочу в этом конкретном коде. unique_ptr имеет правильную семантику владения, но не может работать с неполным типом. Теоретически оболочка должна иметь только накладные расходы на наличие указателя на удалитель.

Есть ли такой тип в C ++ 11 или в библиотеках boost?

ПРИМЕЧАНИЕ. Я понимаю, что могу легко создать этот тип, но я бы предпочел стандартный тип, если это возможно. Кажется, это должен быть базовый тип интеллектуального указателя.


ОБНОВЛЕНИЕ : unique_ptr не является хорошим вариантом. Сначала синтаксические издержки будут смещены. Во-вторых, я не уверен, что его можно безопасно использовать с пользовательским средством удаления. Я проверю, как это может работать.

Ответы [ 3 ]

9 голосов
/ 30 января 2012

Для ясности в отношении unique_ptr: он работает с неполным типом, но если вы используете его в заголовке такого класса:

#include <memory>

class A;

class B
{

std::unique_ptr<A> m_a;

};

Он не будет связываться из-за отсутствующей реализации средства удаления.Это легко исправить: просто определите деструктор хост-класса в cpp, даже если он пустой или должен быть по умолчанию!

// B.hpp
#include <memory>

class A;

class B
{
public:

    B();
    ~B();

private:

std::unique_ptr<A> m_a;

};

// B.cpp

B::B(){} // or =default; (if you have a compiler providing it)
B::~B(){} // or =default; (if you have a compiler providing it)

Кроме того, прочитайте ответы на мой вопрос там: Требуется ли std :: unique_ptr , чтобы знать полное определение T?

И, возможно, взглянуть на то, как идиома pimpl (подразумевающая незавершенный тип в unique_ptr) рекомендуется использоватьХерб Саттер: http://herbsutter.com/gotw/_100/

4 голосов
/ 30 января 2012

На самом деле, unique_ptr может работать с неполными типами, если вы указали пользовательский удалитель.

Однако, в отличие от shared_ptr, это фактически влияет на его тип, поскольку пользовательский удалитель статически корректируется (как второй параметр шаблона).

1 голос
/ 30 января 2012

std::unique_ptr может обработать этот случай, но не с удалением по умолчанию. Вам нужно написать средство удаления, которое может обрабатывать неполный тип, а затем использовать std::unique_ptr<A,MyDeleter>.

...