Inteligentne kursory (Podręcznik programowania C++ nowoczesny)
W nowoczesnych programowania C++, standardowa biblioteka zawiera inteligentne kursory, które są używane w celu zapewnienia, że programy są wolnej pamięci i zasobów przecieki i są bezpieczne wyjątek.
Zastosowań smart wskaźniki
Sprytne wskaźniki są zdefiniowane w std obszaru nazw w <memory> pliku nagłówka.Są one zasadnicze znaczenie dla RAII lub Zasobów nabycia jest Initialialization idiom programowania.Głównym celem tej idiom jest zapewnienie, że nabycie zasobu występuje jednocześnie zainicjować obiektu, tak aby wszystkie zasoby dla obiektu są tworzone i przygotowany w jednej linii kodu.W praktyce, główna zasada RAII jest do przekazania dowolnego zasobu przydzielonej sterty — na przykład dynamicznie przydzielane pamięci lub uchwyty do obiektów systemu — do przydzielonych stosu obiektu, którego destruktora zawiera kod do usunięcia lub wolny zasobu i dowolne skojarzone kodu.
W większości przypadków podczas inicjowania surowego uchwyt wskaźnik lub zasobu wskaż rzeczywistych zasobów przekazać wskaźnik wskaźnik inteligentne natychmiast.W nowoczesnych C++ surowych wskaźników są używane tylko w bloki kodu mały, ograniczony zakres, pętle lub Pomocnik funkcji gdzie ma kluczowe znaczenie i nie ma żadnych nieporozumień dotyczących własności.
Poniższy przykład porównuje deklaracji surowego wskaźnik do deklaracji inteligentne wskaźnika.
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 pokazano w przykładzie, inteligentne wskaźnik jest szablon klasy zadeklarować na stosie i zainicjować przy użyciu wskaźnika surowego, wskazujące obiekt przydzielonej sterty.Po inteligentne wskaźnik jest inicjowany, posiada wskaźnik surowego.Oznacza, że wskaźnik inteligentne odpowiedzialne za usuwanie z pamięci, która określa wskaźnik raw.Destruktor inteligentne wskaźnik zawiera wywołanie, aby usunąć i ponieważ wskaźnik inteligentnych jest zadeklarowana na stosie, jego destruktora jest wywoływana, gdy wskaźnik inteligentne wykracza poza zakres, nawet wtedy, gdy wyjątek jest generowany gdzieś dalej na stos.
Dostęp zhermetyzowany wskaźnika za pomocą operatorów znanych wskaźnik -> i *, której klasy inteligentne wskaźnik overloads zwrócić zhermetyzowany wskaźnik surowego.
Idiom inteligentne wskaźnik C++ jest podobny do tworzenia obiektów w językach takich jak C#: Utwórz obiekt, a następnie zezwolić na system opiekę nad usunięcie go w czasie poprawne.Różnica jest, że oddzielne garbage collector nie działa w tle; pamięć jest zarządzany za pośrednictwem standardowych C++ zakresu zasady, tak aby środowiska wykonawczego jest szybsza i wydajniejsza.
Ważne |
---|
Zawsze twórz Sprytne wskaźniki w oddzielnym wierszu kodu, nigdy nie na liście parametrów, tak, aby przeciek subtelnych zasobu nie będzie występować z powodu niektórych reguł alokacji listy parametrów. |
W poniższym przykładzie jak unique_ptr typu wskaźnik inteligentnego z biblioteki standardowej szablon może zostać wykorzystana do wskaźnika do obiektu dużych hermetyzacji.
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.
Przykład ilustruje następujące czynności zasadnicze dla przy użyciu inteligentne kursory.
Wskaźnik inteligentnych można zadeklarować jako automatyczne zmiennej (lokalne).(Nie używaj new lub malloc wyrażenie wskaźnika inteligentne, sam.)
Parametr typu należy określić typ wskazał na wskaźnik zhermetyzowanego.
Przekazać surowego wskaźnik do new-ed obiektu w konstruktorze inteligentne wskaźnika.(Niektóre funkcje narzędziowe lub konstruktory wskaźnik inteligentne to zrobić dla Ciebie.)
Użyj przeciążony -> i * operatory dostępu do obiektu.
Niech wskaźnik inteligentne, Usuń obiekt.
Inteligentne kursory mają być tak efektywny, jak to możliwe, zarówno pod względem pamięci i wydajności.Na przykład, członek danych tylko w unique_ptr jest zhermetyzowany wskaźnika.Oznacza to, że unique_ptr jest taki sam rozmiar, jak wskaźnik, cztery bajty lub 8 bajtów.Dostęp do wskaźnik zhermetyzowany przy użyciu inteligentnego wskaźnik przeciążony *-> podmioty gospodarcze nie jest znacznie wolniejsze niż dostęp do surowca wskaźniki bezpośrednio.
Inteligentne kursory mają własne funkcje składowe, które są dostępne przy użyciu notacji "kropka".Na przykład niektóre wskaźniki inteligentne STL mają funkcji Członkowskich resetowania, że wskaźnik na własność.Jest to przydatne, gdy chcesz zwolnić pamięć, własnością inteligentne wskaźnika przed inteligentne wskaźnik wykracza poza zakres, jak pokazano w następującym przykładzie.
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...
}
Inteligentne kursory umożliwiają zazwyczaj bezpośredniego dostępu surowego wskaźnika.STL inteligentne kursory mają get Członkowskich funkcji w tym celu i CComPtr ma publicznego p członek klasy.Dostarczając bezpośredni dostęp do podstawowych wskaźnika, można użyć wskaźnik inteligentne zarządzanie pamięci we własnym kodzie i nadal przekazywać surowego wskaźnik do kodu, który nie obsługuje inteligentne kursory.
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());
}
Rodzaje inteligentne kursory
Sekcję podsumowuje różnego rodzaju Sprytne wskaźniki, które są dostępne w środowisku programowania Windows i opisuje, kiedy ich używać.
C++ Standard Library Sprytne wskaźniki
Użyj tych wskaźników inteligentnych jako pierwszy wybór do enkapsulacji wskaźniki do plain old obiekty C++ (POCO).unique_ptr
Pozwala dokładnie jeden właściciel podstawowej wskaźnika.Użyć jako wybór domyślny dla POCO znając dla niektórych, aby wymagać shared_ptr.Można przeniesione do nowego właściciela, ale nie kopiowane lub udostępnione.Zastępuje auto_ptr, który jest niezalecane.Porównaj z boost::scoped_ptr.unique_ptrjest niewielka i skuteczne; rozmiar jest jeden wskaźnik i obsługuje rvalue odwołania do szybkiego wstawiania i pobierania z kolekcji STL.Plik nagłówka: <memory>.Aby uzyskać więcej informacji, zobacz Jak: tworzenie i używanie wystąpienia unique_ptr i unique_ptr Class.shared_ptr
Wskaźnik liczone odniesienia inteligentne.Używana, jeśli chcesz przypisać jeden wskaźnik surowego wielu właścicieli, na przykład, gdy zwraca kopię wskaźnik z kontenera, ale chcesz zachować oryginalny.Wskaźnik raw nie jest usuwany aż wszystkie shared_ptr właściciele zostały przewiezione poza zakresem lub inaczej dały się własność.Rozmiar jest dwa wskaźniki; jeden obiekt i jeden dla bloku sterowania udostępnionym, który zawiera liczbę odwołań.Plik nagłówka: <memory>.Aby uzyskać więcej informacji, zobacz Jak: tworzenie i używanie wystąpienia shared_ptr i shared_ptr Class.weak_ptr
Specjalny rodzaj inteligentne wskaźnik do użycia w połączeniu z shared_ptr.A weak_ptr zapewnia dostęp do obiektu, którego właścicielem jest jeden lub więcej shared_ptr obiektów, ale nie uczestniczy w inwentaryzacji odniesienia.Używana, jeśli chcesz obserwować obiektu, ale nie wymaga on pozostać przy życiu.Wymagane w niektórych przypadkach, aby przerwać odwołania cykliczne między shared_ptr wystąpień.Plik nagłówka: <memory>.Aby uzyskać więcej informacji, zobacz Jak: tworzenie i używanie wystąpienia weak_ptr i weak_ptr Class.
Inteligentne kursory obiektów COM (klasyczny Windows Programowanie)
Podczas pracy z obiektami COM Zawijaj wskaźników interfejsów w wpisz odpowiedni wskaźnik inteligentne.Active Template Library (ATL) definiuje kilka inteligentne kursory do różnych celów.Można również użyć _com_ptr_t typu inteligentne wskaźnik, który podczas tworzenia klasy otoki z plików .tlb używa się kompilator.Nie można dołączyć pliki ATL nagłówka jest najlepszym wyborem.Klasa CComPtr
Użyj, chyba że nie można użyć ATL.Zliczanie przy użyciu odwołań wykonuje AddRef i Release metody.Aby uzyskać więcej informacji, zobacz Jak: tworzenie i używanie instancje CComQIPtr i CComPtr.Klasa CComQIPtr
Podobny do CComPtr , ale przewiduje również uproszczone Składnia wywołania QueryInterface na obiekty COM.Aby uzyskać więcej informacji, zobacz Jak: tworzenie i używanie instancje CComQIPtr i CComPtr.Klasa CComHeapPtr
Inteligentne wskaźnik do obiektów, które używają CoTaskMemFree , aby zwolnić pamięć.Klasa CComGITPtr
Inteligentne wskaźnika dla interfejsów, które są uzyskiwane z tabeli interfejsu globalnego (GIT).Klasa _com_ptr_t
Podobny do CComQIPtr w funkcji, ale nie zależy od ATL nagłówki.
Inteligentne kursory ATL POCO obiekty
Oprócz Sprytne wskaźniki dla obiektów COM ATL definiuje również inteligentne kursory i kolekcje inteligentne kursory, plain old obiektów C++.Klasyczny Windows programowania, te typy są alternatyw użyteczne kolekcje STL, szczególnie w przypadku, gdy kod przenośność nie jest wymagana lub nie chcesz zmieszać modele programowania STL i ATL.Klasa CAutoPtr
Inteligentne wskaźnik wymusza unikatowy własności poprzez przeniesienie własności na kopii.Porównywalne przestarzałe std::auto_ptr klasy.Klasa CHeapPtr
Inteligentne wskaźnika dla obiektów, które są przydzielane przy użyciu c funkcja malloc funkcji.Klasa CAutoVectorPtr
Inteligentne wskaźnika dla tablic, które są przydzielane przy użyciu new[].Klasa CAutoPtrArray
Klasa, która zawiera tablicę CAutoPtr elementy.Klasa CAutoPtrList
Klasa, która hermetyzuje metody listę CAutoPtr węzłów.
Zobacz też
Inne zasoby
Nowoczesne C++ Programming Guide