Przyczyn może być wiele. Aby wymienić kilka z nich:
- Inteligentne wskaźniki niedawno stały się standardem. Do tej pory były częścią innych bibliotek
- Ich głównym zastosowaniem jest unikanie wycieków pamięci; wiele bibliotek nie ma własnego zarządzania pamięcią; Zwykle zapewniają narzędzia i interfejsy API
- Są implementowane jako opakowanie, ponieważ w rzeczywistości są obiektami, a nie wskaźnikami. Co wiąże się z dodatkowym kosztem czasu / przestrzeni w porównaniu do wskaźników surowych; Użytkownicy bibliotek mogą nie chcieć mieć takich narzutów
Edycja : korzystanie z inteligentnych wskaźników jest całkowicie wyborem programisty. To zależy od różnych czynników.
W systemach o krytycznym znaczeniu dla wydajności możesz nie chcieć używać inteligentnych wskaźników, które generują narzut
Projekt, który wymaga kompatybilności wstecznej, możesz nie chcieć używać inteligentnych wskaźników, które mają specyficzne funkcje C ++ 11
Edit2 Istnieje ciąg kilku głosów przeciw w ciągu 24 godzin z powodu poniższego fragmentu. Nie rozumiem, dlaczego odpowiedź jest odrzucana, mimo że poniżej jest tylko sugestią dodatku, a nie odpowiedzią.
Jednak C ++ zawsze ułatwia otwieranie opcji. :) np
template<typename T>
struct Pointer {
#ifdef <Cpp11>
typedef std::unique_ptr<T> type;
#else
typedef T* type;
#endif
};
A w swoim kodzie użyj go jako:
Pointer<int>::type p;
Dla tych, którzy twierdzą, że inteligentny wskaźnik i surowy wskaźnik są różne, zgadzam się z tym. Powyższy kod był tylko pomysłem, w którym można napisać kod, który jest wymienny tylko z a #define
, to nie jest przymus ;
Na przykład T*
musi zostać wyraźnie usunięty, ale inteligentny wskaźnik nie. Możemy mieć szablon, Destroy()
który to obsłuży.
template<typename T>
void Destroy (T* p)
{
delete p;
}
template<typename T>
void Destroy (std::unique_ptr<T> p)
{
// do nothing
}
i użyj go jako:
Destroy(p);
W ten sam sposób dla surowego wskaźnika możemy go skopiować bezpośrednio, a dla inteligentnego wskaźnika możemy użyć specjalnej operacji.
Pointer<X>::type p = new X;
Pointer<X>::type p2(Assign(p));
Gdzie Assign()
jest jak:
template<typename T>
T* Assign (T *p)
{
return p;
}
template<typename T>
... Assign (SmartPointer<T> &p)
{
// use move sematics or whateve appropriate
}