2013-05-27 12 views
6

albumu: http://herbsutter.com/2013/05/22/gotw-5-solution-overriding-virtual-functions/Dlaczego zainicjować unique_ptr za pomocą wywołania make_unique?

Dlaczego powinniśmy napisać:

auto pb = unique_ptr<base>{ make_unique<derived>() }; 

Zamiast:

auto pb = make_unique<derived>(); 

My tylko przypuszczenie, że jeśli chcemy auto, musimy mu pomóc wyprowadzić właściwy typ (base tutaj).

Jeśli tak, to dla mnie to byłoby naprawdę wątpliwa zasługa .. wpisywać auto a następnie wpisz dużo inicjalizacji po prawej stronie = ..

Czego mi brakuje?

+1

Erm, dlaczego? Ponieważ chcesz pierwszą rzecz, a nie drugą? Nie są one równoważne. (Sprawdź 'decltype (pb)') –

+1

jedno jest jasne, jeśli masz smart_pointer z pochodnych, nie możesz łatwo rzucić go do bazy. ponieważ w przeciwieństwie do bazy * x; i wyprowadzono * y; Brak powiązania w hierarchii typów. – Alex

+4

Zastanawiasz się, czy 'unique_ptr pb = make_unique ();' być prostsze? Ponieważ "auto" istnieje, nie oznacza, że ​​musimy z niego korzystać. – FredericS

Odpowiedz

10

Chodzi o to, że pierwsza opcja powoduje, że pb jest unique_ptr<base>, podczas gdy druga opcja powoduje, że pb jest unique_ptr<derived>. To, czy oba są poprawne, czy nie, zależy od tego, co musisz zrobić z pb - ale z pewnością te dwa nie są równoważne.

Jeśli odpowiednia część programu musi pracować z unique_ptr<base> (być może dlatego, że później będziesz to niech się wskazywać na wystąpienie o innym klasy pochodnej), to drugie rozwiązanie jest po prostu nie opłacalne .

Na przykład:

auto pb = unique_ptr<base>{ make_unique<derived>() }; 
// ... 
pb = make_unique<derived2>(); // This is OK 
// ... 

następuje:

auto pb = make_unique<derived>(); 
// ... 
pb = make_unique<derived2>(); // ERROR! "derived2" does not derive from "derived" 
// ... 
+3

Ew, raw 'new' !! – Xeo

+2

Prawdziwi mężczyźni tworzą unikaty. –

+1

@Xeo: 'new'? Kto używa "nowego" ?! : P Zmienione, dziękuję –

3
auto pb = unique_ptr<base>{ make_unique<derived>() }; 

wyżej tworzy unique_ptr<base> że zawiera derived.

auto pb = make_unique<derived>(); 

wyżej tworzy unique_ptr<derived> że zawiera derived.

Podczas zastąpienia drugiego z 1 może być dopuszczalne, oni faktycznie robią różne rzeczy.

Na marginesie, poszukiwanie make_unique w linkowanym artykule powoduje, że ktoś odpowiada na to pytanie.

6

My tylko przypuszczenie, że jeśli chcemy auto, musimy pomóc to wywnioskować odpowiedniego rodzaju (podstawa tutaj).

Dokładnie tak. Bez konwersji, pb byłby wskaźnikiem do derived, który może nie być tym, czego potrzebujesz. Na przykład nie można ponownie przypisać go do własnego obiektu base lub innego obiektu klasy pochodnej.

Jeśli tak, to dla mnie byłoby to naprawdę wątpliwe.

Jestem skłonny zgodzić się. Autor zauważa w comment, że zrobił to, ponieważ lubi używać dedukcji typu tak bardzo, jak to możliwe, z wyraźnymi konwersjami w razie potrzeby. Czas pokaże, czy ten styl stanie się powszechny.

+0

+1 za link do komentarza Herb'a (i twoja miła odpowiedź też :) – emesx

Powiązane problemy