Z C ++ 17 , shared_ptrmogą być używane do zarządzania dynamicznie przydzielonego tablicy. shared_ptrSzablon argumentem w tym przypadku musi być T[N]albo T[]. Więc możesz pisać
shared_ptr<int[]> sp(new int[10]);
Od n4659, [util.smartptr.shared.const]
template<class Y> explicit shared_ptr(Y* p);
Wymagania: Y muszą być kompletne. Wyrażenie delete[] p, kiedy Tjest typem tablicowym lub delete p, gdy Tnie jest typem tablicowym, powinno mieć dobrze zdefiniowane zachowanie i nie powinno generować wyjątków.
...
Uwagi: Gdy Tjest typem tablicowym, ten konstruktor nie będzie uczestniczył w rozpoznawaniu przeciążenia, chyba że wyrażenie delete[] pjest poprawnie sformułowane i albo Tjest U[N]i Y(*)[N]jest konwertowane na T*, albo Tjest
U[]i Y(*)[]jest konwertowane na T*. ...
Aby to obsługiwać, typ pręta element_typejest teraz zdefiniowany jako
using element_type = remove_extent_t<T>;
Dostęp do elementów tablicy można uzyskać za pomocą operator[]
element_type& operator[](ptrdiff_t i) const;
Wymaga: get() != 0 && i >= 0 . Jeśli Tjest U[N], i < N. ...
Uwagi: Gdy Tnie jest typem tablicowym, nie jest określone, czy ta funkcja składowa jest zadeklarowana. Jeśli jest zadeklarowana, nie jest określone, jaki jest jej typ zwrotu, z wyjątkiem tego, że deklaracja (choć niekoniecznie definicja) funkcji powinna być poprawnie sformułowana.
Przed C ++ 17 , shared_ptrmogłoby nie być używane do zarządzania dynamicznie przydzielone tablice. Domyślnie shared_ptrwywoła deletezarządzany obiekt, gdy nie będzie już do niego odwołań. Jednak podczas przydzielania zasobów new[]musisz zadzwonić delete[], a nie deletezwolnić zasób.
Aby poprawnie używać shared_ptrz tablicą, musisz dostarczyć niestandardowy element usuwający.
template< typename T >
struct array_deleter
{
void operator ()( T const * p)
{
delete[] p;
}
};
Utwórz shared_ptr w następujący sposób:
std::shared_ptr<int> sp(new int[10], array_deleter<int>());
Teraz shared_ptrbędzie poprawnie dzwonić delete[]podczas niszczenia zarządzanego obiektu.
Powyższy niestandardowy usuwacz może zostać zastąpiony przez
std::default_deleteczęściowo kierunek typów tablicowe
std::shared_ptr<int> sp(new int[10], std::default_delete<int[]>());
wyrażenie lambda
std::shared_ptr<int> sp(new int[10], [](int *p) { delete[] p; });
Ponadto, jeśli nie potrzebujesz współdzielenia zarządzanego obiektu, unique_ptrlepiej nadaje się do tego zadania, ponieważ ma częściową specjalizację dla typów tablic.
std::unique_ptr<int[]> up(new int[10]); // this will correctly call delete[]
Zmiany wprowadzone przez rozszerzenia C ++ dotyczące podstaw biblioteki
Inną alternatywą przed C ++ 17 do tych wymienionych powyżej była specyfikacja techniczna Library Fundamentals , która została rozszerzona, shared_ptraby umożliwić jej działanie od razu po wyjęciu z pudełka w przypadkach, gdy posiada tablicę obiektów. Aktualny projekt shared_ptrzmian przewidzianych dla tego TS można znaleźć w N4082 . Te zmiany będą dostępne za pośrednictwem std::experimentalprzestrzeni nazw i zawarte w <experimental/memory>nagłówku. Oto kilka istotnych zmian dotyczących obsługi shared_ptrtablic:
- element_typeZmienia się definicja typu pręta
typedef T element_type;
typedef typename remove_extent<T>::type element_type;
- Członek operator[]jest dodawany
element_type& operator[](ptrdiff_t i) const noexcept;
- W przeciwieństwie do unique_ptrczęściowej specjalizacji dla tablic, oba shared_ptr<T[]>i shared_ptr<T[N]>będą prawidłowe i oba spowodują delete[]wywołanie z zarządzanej tablicy obiektów.
template<class Y> explicit shared_ptr(Y* p);
Wymagania : Ymuszą być kompletne. Wyrażenie delete[] p, kiedy Tjest typem tablicowym lub delete p, gdy Tnie jest typem tablicowym, powinno być poprawnie sformułowane, powinno mieć dobrze zdefiniowane zachowanie i nie powinno generować wyjątków. Kiedy Tjest U[N], Y(*)[N]można zamienić na T*; kiedy Tjest U[], Y(*)[]można zamienić na T*; w przeciwnym razie Y*będzie można zamienić na T*.
std::vector. Musisz uważać, aby przekazać tablicę przy użyciu referencji, aby nie robić jej kopii. Składnia dostępu do danych jest czystsza niż shared_ptr, a zmiana jej rozmiaru jest bardzo łatwa. I dostajesz całą dobroć STL, jeśli kiedykolwiek chcesz.