Pomyślałem, że jest bardzo ciekawy, gdy odkryłem, że standard definiuje std::unique_ptr
i std::shared_ptr
na dwa całkowicie różne sposoby dotyczące Deletera, który może posiadać wskaźnik. Oto oświadczenie cppreference::unique_ptr i cppreference::shared_ptr:Typ Deletera w unique_ptr vs. shared_ptr
template<
class T,
class Deleter = std::default_delete<T>
> class unique_ptr;
template< class T > class shared_ptr;
Jak widać unique_ptr "oszczędza" rodzaj The Deleter-obiektu jako szablonu argumentu. To również może być postrzegane w sposób Deleter pobranym z wskaźnikiem później:
// unique_ptr has a member function to retrieve the Deleter
template<
class T,
class Deleter = std::default_delete<T>
>
Deleter& unique_ptr<T, Deleter>::get_deleter();
// For shared_ptr this is not a member function
template<class Deleter, class T>
Deleter* get_deleter(const std::shared_ptr<T>& p);
Może ktoś wyjaśnić racjonalne za tę różnicę? Zdecydowanie faworyzuję koncepcję unique_ptr
, dlaczego nie jest to również stosowane w odniesieniu do shared_ptr
? Ponadto, dlaczego w tym ostatnim przypadku get_deleter
byłaby funkcją nieczłonkowską?
Ktoś będzie musiał wykopać oryginalną propozycję, ale moje wykształcone domysły: brak deletera jako argumentu szablonu sprawia, że 'shared_ptr' jest łatwiejszy w użyciu, ale musisz zapłacić koszty wymazywania typu. Uczynienie 'get_deleter' członkiem spowoduje napisanie ogólnego kodu z' shared_ptr 'bardziej żmudnym - musisz napisać' sp.template get_deleter () 'zamiast' get_deleter (sp) '. Z tego powodu 'std :: get' nie jest członkiem. –
Poszerzenie nieco o to, co @ T.C. powiedział, jednym z celów projektu 'unique_ptr' jest to, że powinien on mieć (bardzo blisko) zero narzutów. Wymazywanie typu deletera jest wygodne, ale wprowadza dodatkowy czas działania z wymazywania, więc jest mniej odpowiedni dla 'unique_ptr' niż dla' shared_ptr' – wakjah
Należy również zauważyć, że z powodu tej różnicy, 'shared_ptr p = make_shared ()' robi to, nawet jeśli 'Base' nie ma wirtualnego destruktora. [dowód] (http://coliru.stacked-crooked.com/a/f3a50f90e00d4e58). –