Udostępnij za pośrednictwem


Jak: tworzenie i używanie wystąpienia shared_ptr

shared_ptr Typ jest inteligentny w standardowa biblioteka języka C++, przeznaczonego dla scenariuszy, w których więcej niż jednego właściciela może być konieczne zarządzać okresem istnienia obiektów w pamięci.Po należy zainicjować shared_ptr można skopiować go, przechodzą przez wartość argumentów funkcji i przypisać ją do innych shared_ptr wystąpień.Wszystkie wystąpienia polecenie do tego samego obiektu, a dzielą wspólny dostęp do jednego "formantu blok", które zwiększa i zmniejsza liczbę odwołań, w każdym przypadku, gdy jest to nowy shared_ptr jest dodawany, wykracza poza zakres lub zostanie zresetowana.W przypadku licznika odwołań osiągnie zero, blok sterowania usuwa zasobów pamięci i tym samym.

Na poniższej ilustracji przedstawiono kilka shared_ptr wystąpień, które wskazują na lokalizację w pamięci jednego.

Wskaźnik udostępnionych

Przykład

O ile to możliwe, użyj make_shared (<memory>) funkcja służąca do tworzenia shared_ptr podczas tworzenia zasobu pamięci po raz pierwszy.make_sharedjest bezpieczna dla wyjątku.Używa tego samego wywołania przydzielić pamięci dla bloku sterowania i zasobu, a tym samym zmniejsza koszty budowy.Jeśli nie skorzystasz z make_shared, a następnie skorzystanie z jawne wyrażenie nowy do utworzenia obiektu, zanim zostanie przekazany do shared_ptr Konstruktor.Poniższy przykład ilustruje różne sposoby oświadczają i zainicjować shared_ptr wraz z nowego obiektu.


// Use make_shared function when possible.
auto sp1 = make_shared<Song>(L"The Beatles", L"Im Happy Just to Dance With You");

// Ok, but slightly less efficient. 
// Note: Using new expression as constructor argument
// creates no named variable for other code to access.
shared_ptr<Song> sp2(new Song(L"Lady Gaga", L"Just Dance"));

// When initialization must be separate from declaration, e.g. class members, 
// initialize with nullptr to make your programming intent explicit.
shared_ptr<Song> sp5(nullptr);
//Equivalent to: shared_ptr<Song> sp5;
//...
sp5 = make_shared<Song>(L"Elton John", L"I'm Still Standing");

Poniższy przykład pokazuje jak deklarować i zainicjować shared_ptr wystąpień, które mają na udostępnionych własności obiektu, która została już przydzielona przez innego shared_ptr.Założenie, że sp2 jest zainicjować shared_ptr.

//Initialize with copy constructor. Increments ref count.
auto sp3(sp2);

//Initialize via assignment. Increments ref count.
auto sp4 = sp2;

//Initialize with nullptr. sp7 is empty.
shared_ptr<Song> sp7(nullptr);

// Initialize with another shared_ptr. sp1 and sp2
// swap pointers as well as ref counts.
sp1.swap(sp2);

shared_ptrjest również pomocne w pojemnikach standardowy szablon biblioteki (STL) podczas korzystania z algorytmów, które kopiowanie elementów.Można zawijać elementów w shared_ptr, a następnie skopiuj go do innych pojemników, przy założeniu, że odpowiedniej pamięci jest prawidłowy, tak długo, jak to potrzebne i nie może.Poniższy przykład pokazuje, jak używać replace_copy_if algorytm na shared_ptr wystąpień w obiekcie vector.

vector<shared_ptr<Song>> v;

v.push_back(make_shared<Song>(L"Bob Dylan", L"The Times They Are A Changing"));
v.push_back(make_shared<Song>(L"Aretha Franklin", L"Bridge Over Troubled Water"));
v.push_back(make_shared<Song>(L"Thal�a", L"Entre El Mar y Una Estrella"));

vector<shared_ptr<Song>> v2;
remove_copy_if(v.begin(), v.end(), back_inserter(v2), [] (shared_ptr<Song> s) 
{
    return s->artist.compare(L"Bob Dylan") == 0;     
});


for_each(v2.begin(), v2.end(), [] (shared_ptr<Song> s)
{
    wcout << s->artist << L":" << s->title << endl;
});

You can use dynamic_pointer_cast, static_pointer_cast, and const_pointer_cast to cast a shared_ptr.Funkcje te przypominają dynamic_cast, static_cast, i const_cast podmiotów gospodarczych.Poniższy przykład pokazuje sposób testowania typu pochodnego każdego elementu w obiekcie vector z shared_ptr z oprzeć klas, a następnie kopiowanie elementów i wyświetlić informacje o nich.

    vector<shared_ptr<MediaAsset>> assets;

    assets.push_back(shared_ptr<Song>(new Song(L"Himesh Reshammiya", L"Tera Surroor")));
    assets.push_back(shared_ptr<Song>(new Song(L"Penaz Masani", L"Tu Dil De De")));
    assets.push_back(shared_ptr<Photo>(new Photo(L"2011-04-06", L"Redmond, WA", L"Soccer field at Microsoft.")));

    vector<shared_ptr<MediaAsset>> photos;

    copy_if(assets.begin(), assets.end(), back_inserter(photos), [] (shared_ptr<MediaAsset> p) -> bool
    {
        // Use dynamic_pointer_cast to test whether
        // element is a shared_ptr<Photo>.
        shared_ptr<Photo> temp = dynamic_pointer_cast<Photo>(p);        
        return temp.get() != nullptr;
    });

    for_each(photos.begin(), photos.end(), [] (shared_ptr<MediaAsset> p)
    {
        // We know that the photos vector contains only 
        // shared_ptr<Photo> objects, so use static_cast.
        wcout << "Photo location: " << (static_pointer_cast<Photo>(p))->location_ << endl;
    });

Można przekazać shared_ptr do innej funkcji w następujący sposób:

  • Przekazać shared_ptr przez wartość.Wywołuje Konstruktor kopiujący, zwiększa liczbę odwołań i sprawia, że wywoływany właściciela.Istnieje małe Kwota narzutów w tej operacji, które mogą okazać się istotne w zależności od liczby shared_ptr obiekty są przekazywanie.Opcja ta jest używana, gdy umowy kodu (dorozumianych lub jawne) między rozmówcą i wywoływany wymaga, aby wywoływany był właściciela.

  • Przekazać shared_ptr przez odwołanie lub odwołanie const.W takim przypadku nie zwiększa licznika odwołań, a wywoływany można uzyskać dostęp wskaźnik, tak długo, jak obiekt wywołujący nie wykracza poza zakres.Lub wywoływany można zdecydować utworzyć shared_ptr na podstawie odwołania, a tym samym staje się właścicielem udostępnionego.Użyj tej opcji, gdy obiekt wywołujący nie ma wiedzy wywoływany, lub gdy trzeba przekazać shared_ptr , bez operacji kopiowania, ze względu na wydajność.

  • Przekazać wskaźnik podstawowych lub odwołanie do obiektu źródłowego.To umożliwia wywoływany do korzystania z obiektu, ale nie powoduje włączenia go na własność akcji lub wydłużyć okres.Jeśli wywoływany tworzy shared_ptr z surowego wskaźnik nowych shared_ptr jest niezależna od oryginału, a nie obejmuje kontroli podstawowych zasobów.Ta opcja kontrakt między rozmówcą i wywoływany wyraźnie określa, że obiekt wywołujący zachowuje własność shared_ptr okres istnienia.

  • Podejmując jak przekazać shared_ptr, określić, czy jest wywoływany udostępnić prawa własnooci podstawowych zasobów."Właściciel" jest obiekt lub funkcja, który można przechowywać podstawowych zasobów przy życiu tak długo, jak wymaga tego.Jeżeli obiekt wywołujący musi zagwarantować, że wywoływany można przedłużyć żywotność wskaźnik poza jego żywotność (funkcja), użyj pierwszej opcji.Jeżeli nie zależy, czy wywoływany rozciąga się okres istnienia, przechodzą przez odwołanie i powiadom wywoływany, skopiuj go, czy nie.

  • Jeśli trzeba dać dostęp funkcja pomocnika do podstawowej wskaźnika, a wiedzieć, funkcja pomocnicza będzie tylko za pomocą wskaźnika i przekazać przed wywołujący funkcja zwraca, a następnie tej funkcji nie ma własności wskaźnik podstawowych akcji.Po prostu ma dostęp wskaźnik w okresie użytkowania obiektu wywołującego do shared_ptr.W takim przypadku bezpiecznie przekazać shared_ptr przez odwołanie lub przekazać wskaźnik surowego lub odwołanie do podstawowych obiektów.Przekazując w ten sposób zapewnia korzyści mała wydajność i może również ułatwić express Twoich zamiarów programowania.

  • Czasami, na przykład w std:vector<shared_ptr<T>>, może być konieczne przejścia każdego shared_ptr do ciała Wyrażenie lambda lub funkcji o nazwie obiektu.Jeśli lambda lub funkcja nie przechowuje wskaźnik, a następnie przekazać shared_ptr w odniesieniu do unikanie stosowania ten konstruktor dla każdego elementu.

W poniższym przykładzie pokazano sposób shared_ptr overloads różnych operatorów porównania w celu umożliwienia porównań wskaźnik wolnej pamięci, którego właścicielem jest shared_ptr wystąpień.


// Initialize two separate raw pointers.
// Note that they contain the same values.
auto song1 = new Song(L"Village People", L"YMCA");
auto song2 = new Song(L"Village People", L"YMCA");

// Create two unrelated shared_ptrs.
shared_ptr<Song> p1(song1);    
shared_ptr<Song> p2(song2);

// Unrelated shared_ptrs are never equal.
wcout << "p1 < p2 = " << std::boolalpha << (p1 < p2) << endl;
wcout << "p1 == p2 = " << std::boolalpha <<(p1 == p2) << endl;

// Related shared_ptr instances are always equal.
shared_ptr<Song> p3(p2);
wcout << "p3 == p2 = " << std::boolalpha << (p3 == p2) << endl; 

Zobacz też

Koncepcje

Inteligentne kursory (Podręcznik programowania C++ nowoczesny)