2012-12-25 15 views
6

Mam proste pytanie noob, że nie mogę znaleźć odpowiedzi na:Konwersja obiektu std :: unique_ptr

W C++ jak można przekonwertować zwykłego obiektu

int i; 

do std::unique_ptr?

std::unique_ptr<int> iptr = &i; //invalid 
std::unique_ptr<int> iptr = static_cast<std::unique_ptr<int>>(&i); //invalid 

Dzięki.

Odpowiedz

11

Nie. Ten obiekt nie może zostać usunięty przez delete, co zrobi unique_ptr. Musisz

auto iptr = make_unique<int>(); 

Tutaj definiujemy make_unique jako funkcji użyteczności identycznym make_shared, które powinny być standardowe, ale niestety było pominąć. Oto krótka implementacja:

template<typename T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args) { 
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); 
} 
+0

Chociaż dla kompletności funkcja byłaby przyjemna, ale nie sądzę, że została pominięta tak bardzo, jak nie jest potrzebna. Pamiętaj, że make_shared rozwiązuje problem przydzielania dwóch obiektów naraz (nie ma równoważnego konstruktora), podczas gdy unique_ptr po prostu tego nie potrzebuje (ma zero na podstawie projektu). –

+0

To nie prawda. Nadal istnieje wyjątek, który nie jest bezpieczny, jeśli skonstruujesz dwa unique_ptrs w jednym wywołaniu funkcji, które na przykład make_unique zapisuje. – Puppy

+0

Nie można tego uniknąć, tworząc w tym miejscu unique_ptr? 'func (unique_ptr (new T), unique_ptr (new U))' –

4

Nie. i nie został przydzielony dynamicznie, więc nie trzeba go usuwać. Jeśli owinąłbyś inteligentny wskaźnik wokół jego adresu, w pewnym momencie zrobiłby on delete &i i dałby Ci niezdefiniowane zachowanie. należy owinąć tylko coś trzeba new ed w inteligentny wskaźnik, tak jak poniżej:

std::unique_ptr<int> ptr(new int(5)); 

Sensem inteligentnego wskaźnika jest to, że udaje żywotność dynamicznie przydzielonego obiektu dla Ciebie. i ma automatyczny czas przechowywania, więc zostanie zniszczony na końcu jego zakresu. Nie potrzebujesz niczego, aby ci w tym pomóc.

0

Kiedy unique_ptr zostanie zniszczony, co by się stało? Lub w inny sposób, gdy zmienna wydostanie się poza zasięg? Nie ma sensu faktycznie

1

Wierzę, że to będzie działać:

int i; 
auto deleter = [](int *ptr){}; 
std::unique_ptr<int, decltype(deleter)> iptr(&i, deleter); 

trzeba dostarczyć niestandardową Deleter, że nic nie robi. Domyślny deleter nie może usunąć automatycznej zmiennej nieprzydzielonej przez new. (Jednak to pokonuje cel użycia inteligentnego wskaźnika, ale pokazuje, że jest to możliwe).

Powiązane problemy