Inteligentní ukazatelů (Příručka programování moderních C++)
V moderní programování C++, standardní knihovna obsahuje inteligentní ukazatele, které slouží k zajištění, že programy jsou volné paměti a prostředků nevrací a jsou bezpečné výjimku.
Použití inteligentních ukazatele
Inteligentní ukazatele jsou definovány v std obor názvů <memory> hlavičky souboru.Jsou velmi důležité pro RAII nebo Prostředku pořízení je Initialialization idiomu programování.Hlavním cílem této idiomu je zajistit, aby pořízení prostředku při inicializaci objektu tak, že jsou všechny prostředky pro objekt vytvořen a připraven na jeden řádek kódu.Z praktického hlediska je hlavní zásadou RAII poskytnout vlastnictví libovolného zdroje přidělené haldy – například paměť přidělená dynamicky nebo úchyty objektu systému – objekt zásobníku přidělené jehož destruktoru obsahuje kód odstranit nebo uvolnit zdroje a také všechny přidružené vyčištění kódu.
Ve většině případů při můžete inicializovat raw ukazatel nebo zdroj úchyt pro skutečný zdroj, předejte ukazatel inteligentní ukazatel okamžitě.V jazyce C++ moderní raw ukazatele používají pouze v bloky kódu malý omezený rozsah, smyčky nebo pomocné funkcí kde výkon je důležité a neexistuje možnost záměny o vlastnictví.
Následující příklad porovnává raw ukazatel prohlášení prohlášení inteligentní ukazatel.
void UseRawPointer()
{
// Using a raw pointer -- not recommended.
Song* pSong = new Song(L"Nothing on You", L"Bruno Mars");
// Use pSong...
// Don't forget to delete!
delete pSong;
}
void UseSmartPointer()
{
// Declare a smart pointer on stack and pass it the raw pointer.
unique_ptr<Song> song2(new Song(L"Nothing on You", L"Bruno Mars"));
// Use song2...
wstring s = song2->duration_;
//...
} // song2 is deleted automatically here.
Jak je uvedeno v příkladu je inteligentní ukazatel šablona třídy, deklarovat v zásobníku a inicializaci pomocí raw ukazatel, který odkazuje na objekt přidělení haldy.Po inicializaci inteligentní ukazatel vlastní raw ukazatel.Znamená, že inteligentní ukazatel je odpovědný za odstranění paměť, která určuje ukazatel raw.Obsahuje ukazatel na inteligentní objekt volání odstranit a protože inteligentní ukazatel je deklarována v zásobníku, jeho destruktoru je vyvoláno inteligentní ukazatel dostane mimo rozsah, i když někde dále nahoru zásobníku je vyvolána výjimka.
Přístup pomocí operátorů známé ukazatel zapouzdřené ukazatel -> a *, které třídy inteligentní ukazatel přetížení vrátit zapouzdřené raw ukazatel.
Vytvoření objektu v jazyky jako C# se podobá idiomu inteligentní ukazatel C++: vytvoření objektu a nechat systém starat o odstranění ve správný čas.Rozdíl je, že žádné samostatné garbage collector běží na pozadí; paměť je spravován prostřednictvím standard C++ oborů pravidla tak, aby prostředí runtime je rychlejší a efektivnější.
Důležité |
---|
Vždy vytvořte inteligentní ukazatele na samostatný řádek kódu nikdy v seznamu parametrů, tak únik jemných prostředků nebude dochází z důvodu určitá pravidla přidělení seznamu parametr. |
Následující příklad ukazuje jak unique_ptr inteligentní ukazatel z knihovny standardní šablony můžete použít k zapouzdření ukazatel na velké objektu.
class LargeObject
{
public:
void DoSomething(){}
};
void ProcessLargeObject(const LargeObject& lo){}
void SmartPointerDemo()
{
// Create the object and pass it to a smart pointer
std::unique_ptr<LargeObject> pLarge(new LargeObject());
//Call a method on the object
pLarge->DoSomething();
// Pass a reference to a method.
ProcessLargeObject(*pLarge);
} //pLarge is deleted automatically when function block goes out of scope.
Příklad ukazuje následující základní kroky pro použití inteligentních ukazatele.
Inteligentní ukazatel Deklarujte jako automatické (místní) Proměnná.(Nepoužívejte new nebo malloc inteligentní ukazatele samotný výraz.)
Parametr typu zadejte typ poukázala na zapouzdřené ukazatel.
Předat raw ukazatele new-ed objektu v konstruktoru inteligentní ukazatel.(Některé funkce nástroje nebo inteligentní ukazatel konstruktory provést automaticky.)
Použít přetížená -> a * operátory pro přístup k objektu.
Umožňují inteligentní ukazatel odstranit objekt.
Inteligentní ukazatele jsou navrženy se jako nejúčinnější jak z paměti a výkon.Například člen pouze data v unique_ptr je zapouzdřený ukazatel.To znamená, že unique_ptr stejnou velikost jako tento ukazatel bajtů čtyři nebo osm bajtů.Přístup zapouzdřené ukazatele pomocí inteligentní přetížena ukazatel * a - > operátory není výrazně pomalejší než přístup k raw ukazatele přímo.
Inteligentní ukazatele mají své vlastní členské funkce, které jsou přístupné pomocí zápisu "tečka".Například některé ukazatele inteligentní STL mají obnovit členské funkce, které uvolní vlastnictví ukazatel.To je užitečné, když chcete uvolnit paměť vlastněných inteligentní ukazatel před inteligentní ukazatel dostane mimo rozsah, jak ukazuje následující příklad.
void SmartPointerDemo2()
{
// Create the object and pass it to a smart pointer
std::unique_ptr<LargeObject> pLarge(new LargeObject());
//Call a method on the object
pLarge->DoSomething();
// Free the memory before we exit function block.
pLarge.reset();
// Do some other work...
}
Inteligentní ukazatele obvykle umožňují přímý přístup k jejich raw ukazatel.Jste inteligentní ukazatele STL get pro tento účel členské funkce a CComPtr má veřejný p člen třídy.Poskytuje přímý přístup k podkladové ukazatel, můžete pomocí inteligentní ukazatel ke správě paměti ve vlastním kódu a stále předat kód, který nepodporuje inteligentní ukazatele ukazatel raw.
void SmartPointerDemo4()
{
// Create the object and pass it to a smart pointer
std::unique_ptr<LargeObject> pLarge(new LargeObject());
//Call a method on the object
pLarge->DoSomething();
// Pass raw pointer to a legacy API
LegacyLargeObjectFunction(pLarge.get());
}
Druhy inteligentní ukazatele
V následující části shrnuje různé druhy inteligentní ukazatelů, které jsou k dispozici v programovacím prostředí Windows a popis jejich použití.
C++ Standard Library inteligentní ukazatele
Pomocí těchto ukazatelů inteligentní jako první volbou pro zapouzdření ukazatele na obyčejný starých objektů C++ (POCO).unique_ptr
Umožňuje přesně jeden vlastník základní ukazatele.Použít jako výchozí volba pro POCO, pokud si nejste jisti, že vyžadují shared_ptr.Mohou přesunuty do nového vlastníka, ale není zkopírován nebo sdílené.Nahradí auto_ptr, který se již nepoužívá.Porovnat s boost::scoped_ptr.unique_ptrje malý a efektivní; velikost je jeden ukazatel a podporuje rvalue odkazy pro rychlé vložení a načítání z kolekce STL.Soubor záhlaví: <memory>.Další informace naleznete v tématu Jak: vytvoření a použití instance unique_ptr a unique_ptr Class.shared_ptr
Počítají referenční inteligentní ukazatel.Použijte, pokud chcete přiřadit jeden ukazatel raw více vlastníků, například vrátit kopii ukazatel z kontejneru, ale chcete zachovat původní.Raw ukazatel odstraněn až všechny shared_ptr vlastníci šly mimo rozsah nebo jinak udělili vlastnictví.Velikost je dva ukazatele; jeden objekt a jeden pro řízení sdílení blok, který obsahuje počet odkazů.Soubor záhlaví: <memory>.Další informace naleznete v tématu Jak: vytvoření a použití instance shared_ptr a shared_ptr Class.weak_ptr
Zvláštní případ inteligentní ukazatel pro použití ve spojení s shared_ptr.A weak_ptr poskytuje přístup k objektu, který je vlastněn jedním nebo více shared_ptr instancí, ale není součástí počítání odkazů.Použití chcete sledovat objektu, ale není nutná zůstat naživu.V některých případech nutné přerušit cyklické odkazy mezi shared_ptr instance.Soubor záhlaví: <memory>.Další informace naleznete v tématu Jak: vytvoření a použití instance weak_ptr a weak_ptr Class.
Inteligentní ukazatele pro objekty COM (klasické Windows programování)
Při práci s objekty COM zalomit ukazatele rozhraní typu inteligentní příslušné ukazatele.Aktivní šabloně knihovny (ATL) definuje několik inteligentních ukazatelů pro různé účely.Můžete také použít _com_ptr_t typu inteligentní ukazatel kompilátor používá při vytváření tříd obálky z .tlb souborů.Pokud chcete zahrnout záhlaví souborů ATL je nejlepší volbou.Třída CComPtr
Použijte, pokud nelze použít ATL.Provede inventuru pomocí odkazu AddRef a Release metod.Další informace naleznete v tématu Jak: vytvoření a použití instance CComQIPtr a CComPtr.Třída CComQIPtr
Podobná CComPtr , ale také poskytuje zjednodušené syntaxe pro volání QueryInterface objekty modelu COM.Další informace naleznete v tématu Jak: vytvoření a použití instance CComQIPtr a CComPtr.Třída CComHeapPtr
Inteligentní objekty, které používají ukazatele CoTaskMemFree paměti.Třída CComGITPtr
Inteligentní ukazatel rozhraní, které jsou získány z tabulky global interface (GIT).Třída _com_ptr_t
Podobná CComQIPtr funkce, ale není závislá na ATL záhlaví.
Inteligentní ukazatele ATL POCO objektů
Vedle ukazatele inteligentní objekty COM ATL definuje také inteligentní ukazatele a kolekce smart ukazatele pro obyčejný starých objektů C++.V klasické Windows programování, tyto typy jsou užitečné alternativy kolekce STL, zvláště, když není požadován kód přenositelnost nebo když nechcete promíchá modely programování STL a ATL.Třída CAutoPtr
Inteligentní ukazatel převedení vlastnictví na kopii vynucuje jedinečný vlastnictví.Srovnatelné nepoužívaných std::auto_ptr třídy.Třída CHeapPtr
Inteligentní ukazatel pro objekty, které jsou přiděleny pomocí c MALLOC funkce.Třída CAutoVectorPtr
Inteligentní ukazatel pro pole, které jsou přiděleny pomocí new[].Třída CAutoPtrArray
Třída, která zapouzdřuje pole CAutoPtr prvky.Třída CAutoPtrList
Třída, která Zapouzdřuje metody pro práci s seznam CAutoPtr uzlů.
Viz také
Další zdroje
Moderní Příručka programování v jazyce C++