2012-01-30 6 views
8

Czy istnieje standardowa klasa wskaźnika (lub funkcja Boost), która jest wskaźnikiem niewspółużytkowanym, który działa z niekompletnymi typami? Przeszedłem przez standard C++ 11 i bibliotekę boost i nie mogę go znaleźć, choć wydaje się bardzo przydatny.Niewspółużytkowany wskaźnik inteligentny z niekompletnymi typami

Na przykład chciałbym móc tworzyć nieprzezroczyste typy za pomocą inteligentnego wskaźnika.

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

A jest typu nieprzezroczysty, które mogą być wykorzystywane do różnych zadań. Użytkownik powyższego interfejsu ma tylko niepełną definicję A, ale powinien mieć możliwość usunięcia/zresetowania wskaźnika. Wiem, że powyższe można zrobić z shared_ptr, ale to ma narzut, którego nie chcę w tym szczególnym kodzie. unique_ptr ma odpowiednią semantykę własności, ale nie może pracować z niekompletnym typem. Teoretycznie owijka powinna potrzebować tylko narzut posiadania wskaźnika do deletera.

Czy istnieje taki typ w C++ 11 lub w bibliotekach boost?

UWAGA: Rozumiem, że mogę łatwo zbudować ten typ, ale preferuję standardowy typ, jeśli to możliwe. Wygląda na to, że powinien to być podstawowy typ inteligentnego wskaźnika.


UPDATE: unique_ptr nie wydaje się być dobrym rozwiązaniem. Po pierwsze narzut składni będzie kompensacją. Po drugie, nie jestem przekonany, czy można go bezpiecznie stosować z niestandardowym deleterem. Sprawdzę, jak to działa.

Odpowiedz

4

W rzeczywistości, unique_ptr może pracować z niepełnymi typami, o ile określa się niestandardowy deleterem.

Jednak w przeciwieństwie do shared_ptr ma to wpływ na jego typ, ponieważ niestandardowy deleter jest precyzyjnie ustalany (jako drugi parametr szablonu).

+0

Chociaż pod względem technicznym jest prawdą, użycie tego bezpośrednio jest niepoprawne syntaktycznie. Nie możesz po prostu zrobić 'ptr_type (new T)', ale zakładając, że szablon jest poprawny, musisz wykonać 'ptr_type (new T, T :: ~ T)'. –

+1

W rzeczywistości, patrząc ściśle 'unique_ptr' nie można użyć niestandardowego deletera ze stanem. Funkcja 'reset' nie pozwala na określenie deletera, tylko konstruktor robi, dlatego niestandardowy aspekt usuwania' unique_ptr' jest częściowo uszkodzony. –

+0

Nie ma potrzeby stosowania niestandardowego narzędzia usuwającego, typ musi być wypełniony tylko wtedy, gdy zostanie wywołany destruktor 'unikalnego_ptr', co oznacza, że ​​można zdefiniować destruktor po zakończeniu utrzymywanej klasy. – Xeo

1

std::unique_ptr poradzi sobie z tym przypadkiem, ale nie z domyślnym deleterem. Musisz napisać narzędzie, które poradzi sobie z niekompletnym typem, a następnie użyć std::unique_ptr<A,MyDeleter>.

9

Aby być jasne, o unique_ptr: to nie działa z niepełną typu, ale jeśli używasz go w nagłówku klasy tak:

#include <memory> 

class A; 

class B 
{ 

std::unique_ptr<A> m_a; 

}; 

To nie odwołuje z powodu brakującej implementacji Deleter. Jest łatwa do rozwiązania: wystarczy zdefiniować de destruktor klasy hosta w cpp, nawet jeśli jest pusty lub powinien być domyślny!

// 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) 

Również przeczytać odpowiedzi na moje pytanie tam: Is std::unique_ptr<T> required to know the full definition of T?

A może przyjrzeć jak pimpl idiom (sugerując uncomplete wpisać unique_ptr) jest zalecany do implmented przez Herb Sutter: http://herbsutter.com/gotw/_100/

+1

To nie jest użytek, którego chcę. Chcę użyć wskaźnika w zwracanej wartości funkcji, w miejscu, w którym wywołujący nigdy nie zobaczy pełnego typu. –