Jak: vytvoření a použití instance weak_ptr
Někdy musí objekt uložit způsobem základní objekt pro přístup shared_ptr , aniž by počet odkazů na být zvýšen.Obvykle k této situaci dochází při mají cyklické odkazy mezi shared_ptr instance.
Optimální je zabránit sdílené vlastnictví ukazatele, kdykoli je to možné.Ale pokud musí mít sdílené vlastnictví shared_ptr případech vyhnout cyklické odkazy mezi nimi.Cyklické odkazy jsou nevyhnutelné nebo dokonce výhodnější z nějakého důvodu, použijte weak_ptr poskytnout jednu nebo více vlastníků slabá odkaz na jiné shared_ptr.Pomocí weak_ptr, můžete vytvořit shared_ptr , spojuje stávající sadu souvisejících instance, ale pouze pokud podkladové zdroje paměti je stále platný.A weak_ptr sám neúčastní počítání odkazů, a proto ji nelze zabránit počet odkazů na nulu.Lze však použít weak_ptr při pokusu získat novou kopii shared_ptr s, který nebyl inicializován.Pokud paměť již byla odstraněna, bad_weak_ptr je vyvolána výjimka.Pokud paměť je stále platný, nový ukazatel sdílené zvýší počet odkazů a zaručuje paměť bude platit tak dlouho, dokud shared_ptr proměnné zůstane v oboru.
Příklad
Následující příklad kódu ukazuje případ, kdy weak_ptr se používá k zajištění řádné odstranění objektů, které mají kruhové závislosti.Přezkoumat příklad předpokládá, že byl vytvořen pouze poté, co byly považovány za alternativní řešení.Controller Objekty představují některé aspekty proces počítače a pracují nezávisle.Každý řadič musí být schopen kdykoli zjistit stav ostatních řadičů a každý z nich obsahuje soukromého vector<weak_ptr<Controller>> pro tento účel.Každý vektor obsahuje cyklický odkaz a proto weak_ptr instance jsou použity namísto shared_ptr.
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class Controller
{
public:
int Num;
wstring Status;
vector<weak_ptr< Controller >> others;
explicit Controller(int i) : Num(i) , Status(L"On")
{
wcout << L"Creating Controller" << Num << endl;
}
~Controller()
{
wcout << L"Destroying Controller" << Num << endl;
}
// Demonstrates how to test whether the
// pointed-to memory still exists or not.
void CheckStatuses() const
{
for_each(others.begin(), others.end(), [] (weak_ptr<Controller> wp)
{
try
{
auto p = wp.lock();
wcout << L"Status of " << p->Num << " = " << p->Status << endl;
}
catch (bad_weak_ptr b)
{
wcout << L"Null object" << endl;
}
});
}
};
void RunTest()
{
vector<shared_ptr< Controller >> v;
v.push_back(shared_ptr< Controller >(new Controller(0)));
v.push_back(shared_ptr< Controller > (new Controller(1)));
v.push_back(shared_ptr< Controller > (new Controller(2)));
v.push_back(shared_ptr< Controller > (new Controller(3)));
v.push_back(shared_ptr< Controller > (new Controller(4)));
// Each controller depends on all others not being deleted.
// Give each controller a pointer to all the others.
for (int i = 0 ; i < v.size(); i++)
{
for_each(v.begin(), v.end(), [v,i] (shared_ptr<Controller> p)
{
if(p->Num != i)
{
v[i]->others.push_back(weak_ptr<Controller>(p));
wcout << L"push_back to v[" << i << "]: " << p->Num << endl;
}
});
}
for_each(v.begin(), v.end(), [](shared_ptr<Controller>& p)
{
wcout << L"use_count = " << p.use_count() << endl;
p->CheckStatuses();
});
}
int main()
{
RunTest();
wcout << L"Press any key" << endl;
char ch;
cin.getline(&ch, 1);
}
Jako pokus, měnit vektor others se vector<shared_ptr<Controller>>a ve výstupu, Všimněte si, že jsou spuštěny žádné destruktory při TestRun vrátí.
Viz také
Koncepty
Inteligentní ukazatelů (Příručka programování moderních C++)