Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Modern C++ programlamada Standart Kitaplık, programların bellek ve kaynak sızıntılarından arındığından ve özel durum açısından güvenli olduğundan emin olmak için kullanılan akıllı işaretçiler içerir.
Akıllı işaretçiler için kullanım alanları
Akıllı işaretçiler, bellekstd
<ad alanında tanımlanır. RAII veya Kaynak Alımı Başlatma programlama deyimi için çok önemlidir. Bu deyimin ana amacı, kaynak alımının nesnenin başlatılmasıyla aynı anda gerçekleşmesini sağlamaktır; böylece nesne için tüm kaynaklar bir kod satırında oluşturulur ve hazır hale getirilir. Pratikte temel RAII prensibi, yığın tarafından ayrılan herhangi bir kaynağın sahipliğini örneğin, dinamik olarak ayrılan belek veya sistem nesnesi tanıtıcıları, yok edicisi kaynağı silmek veya boşaltmak için gereken kodu ve herhangi bir temizleme kodunu içeren ve yığın tarafından ayrılan bir nesneye vermektir.
Çoğu durumda gerçek bir kaynağı işaret etmek ve işaretçiyi hemen bir akıllı işaretçiye dönüştürmek için bir ham işaretçi veya kaynak tanıtıcısı kullanırsınız. Modern C++ programlamada, ham işaretçiler yalnızca performansın önemli olduğu ve sahiplik konusunda karışıklık olma ihtimali bulunmayan kapsam, döngü veya yardımcı işlevler açısından sınırlı olan küçük kod engellerinde kullanılır.
Aşağıdaki örnek, bir ham işaretçi bildirimini bir akıllı işaretçi bildirimi ile karşılaştırır.
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.
Akıllı işaretçi, örnekte gösterildiği gibi, yığında bildirdiğiniz ve yığın tarafından ayrılan nesneyi gösteren ham işaretçiyi kullanarak başlattığınız bir sınıf şablonudur. Akıllı işaretçi başlatıldıktan sonra ham işaretçiyi üstlenir. Bu, akıllı işaretçinin, ham işaretçinin belirttiği belleği silmekten sorumlu olduğu anlamına gelir. Akıllı işaretçi yok edici silinecek çağrıyı içerir ve akıllı işaretçi yığında bildirildiğinden, akıllı işaretçi kapsam dışına çıktığında, yığının daha ileri bir yerinde bir özel durum olsa bile, yok edicisi çağrılır.
Kapsüllenmiş işaretçiye, ->
bilinen işaretçi işleçlerini ve *
akıllı işaretçi sınıfının kapsüllenmiş ham işaretçiyi döndürmek için aşırı yüklendiği öğesini kullanarak erişin.
C++ akıllı işaretçi deyimi, C# gibi dillerde nesne oluşturmaya benzer: Nesneyi oluşturursunuz ve ardından sistemin doğru zamanda bunu silmesine izin verirsiniz. Fark arka planda ayrı bir çöp toplayıcının çalışmamasıdır; bellek standart C++ kapsama kuralları ile yönetilir, bu nedenle çalışma zamanı ortamı daha hızlı ve daha verimlidir.
Önemli
Akıllı işaretçileri, asla parametre listesinde değil, her zaman ayrı bir kod satırında oluşturun, böylece belli parametre listesi ayırma kuralları nedeniyle küçük kaynak sızıntıları meydana gelmesine engel olursunuz.
Aşağıdaki örnek, C++ Standart Kitaplığı'ndan akıllı unique_ptr
işaretçi türünün büyük bir nesneye yönelik bir işaretçiyi kapsüllemek için nasıl kullanılabileceğini gösterir.
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.
Örnek akıllı işaretçileri kullanmak için aşağıdaki temel adımları gösterir.
Akıllı işaretçiyi otomatik bir (yerel) değişken olarak bildirin. (Akıllı işaretçinin
new
kendisinde veyamalloc
ifadesini kullanmayın.)Tür parametresinde kapsüllenen işaretçinin, işaret edilen türünü belirtin.
Ham işaretçiyi
new
akıllı işaretçi oluşturucusunda -ed nesnesine geçirin. (Bazı yardımcı program işlevleri veya akıllı işaretçi oluşturucuları bunu sizin için yapar.)Nesnesine erişmek için aşırı yüklenmiş
->
ve*
işleçlerini kullanın.Akıllı işaretçinin nesneyi silmesine izin verin.
Akıllı işaretçiler bellek ve performans açısından mümkün olduğunda verimli olmak için tasarlanmıştır. Örneğin içindeki tek veri üyesi unique_ptr
kapsüllenmiş işaretçidir. Bu, unique_ptr
dört bayt veya sekiz bayt olan işaretçiyle tam olarak aynı boyutta olduğu anlamına gelir. * ve -> işleçleri aşırı yüklenmiş akıllı işaretçiyi kullanarak kapsüllenmiş işaretçiye erişmek ham işaretçilere doğrudan erişmekten önemli ölçüde daha yavaş değildir.
Akıllı işaretçiler, "nokta" gösterimi kullanılarak erişilen kendi üye işlevlerine sahiptir. Örneğin, bazı C++ Standart Kitaplığı akıllı işaretçileri, işaretçinin sahipliğini serbest bırakan bir sıfırlama üyesi işlevine sahiptir. Bu, aşağıdaki örnekte gösterildiği şekilde akıllı işaretçi kapsam dışında çıkmadan önce akıllı işaretçinin sahip olduğu belleği boşaltmak istediğinizde yararlıdır.
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...
}
Akıllı işaretçiler genelde ham işaretçilerine doğrudan erişmek için bir yol sağlar. C++ Standart Kitaplığı akıllı işaretçilerinin bu amaçla bir get
üye işlevi vardır ve CComPtr
ortak p
sınıf üyesi vardır. Temel alınan işaretçiye doğrudan erişim sağladığınızda, akıllı işaretçiyi kendi kodunuzla bellek yönetmek amacıyla kullanırken, ham işaretçiyi de hala akıllı işaretçileri desteklemeyen koda geçirebilirsiniz.
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());
}
Akıllı işaretçi türleri
Aşağıdaki bölümde Windows programlama ortamında bulunan farklı türden akıllı işaretçiler özetlenir ve bunların ne zaman kullanılacağı açıklanır.
C++ Standart Kitaplığı akıllı işaretçileri
Bu akıllı işaretçileri eski C++ nesnelerine (POCO) işaretçi kapsüllemek için ilk seçenek olarak kullanın.
unique_ptr
Temel alınan işaretçi için, kesin olarak tek bir sahibe izin verir. poco için varsayılan seçenek olarak kullanın eğer bir ihtiyacınızshared_ptr
olduğunu kesin olarak bilmiyorsanız. Bir yeni kullanıcıya taşınabilir, ancak kopyalanamaz veya paylaşılamaz.auto_ptr
kullanım dışı olan öğesinin yerini alır. ileboost::scoped_ptr
karşılaştırın.unique_ptr
küçük ve verimlidir; boyut bir işaretçidir ve C++ Standart Kitaplık koleksiyonlarından hızlı ekleme ve alma için rvalue başvurularını destekler. Üst bilgi dosyası:<memory>
. Daha fazla bilgi için bkz . Nasıl yapılır: unique_ptr Örnekleri oluşturma ve kullanma ve unique_ptr Sınıfı.shared_ptr
Başvuru sayımı olan akıllı işaretçi. Birden fazla sahibe tek bir ham işaretçi atamak istediğinizde kullanın, örnek olarak bir kapsayıcıdan işaretçi kopyası döndürüp orijinalini saklamak istediğinizde kullanın. Ham işaretçi, tümshared_ptr
sahipler kapsamın dışına çıkana veya başka bir şekilde sahipliklerinden vazgeçene kadar silinmez. Boyut iki işaretçi kadardır; biri nesne için ve biri başvuru sayısını içeren paylaşılan denetim bloğu için. Üst bilgi dosyası:<memory>
. Daha fazla bilgi için bkz. Nasıl yapılır: shared_ptr Örnekleri ve shared_ptr Sınıfı Oluşturma ve Kullanma.weak_ptr
ileshared_ptr
birlikte kullanmak için özel durumlu akıllı işaretçi. ,weak_ptr
bir veya daha fazlashared_ptr
örneğe ait olan ancak başvuru sayımına katılmayan bir nesneye erişim sağlar. Bir nesneyi görmek istiyorsanız ancak canlı kalmasını istemiyorsanız kullanın. Bazı durumlarda örnekler arasındakishared_ptr
döngüsel başvuruları kesmek için gereklidir. Üst bilgi dosyası:<memory>
. Daha fazla bilgi için bkz. Nasıl yapılır: weak_ptr Örnekleri ve weak_ptr Sınıfı Oluşturma ve Kullanma.
COM nesneleri için akıllı işaretçiler (klasik Windows programlama)
COM nesneleriyle çalışırken, arabirim işaretçilerini uygun akıllı işaretçi türüne sarın. Etkin Şablon Kitaplığı (ATL) çeşitli amaçlar için birçok akıllı işaretçi tanımlar. Derleyicinin _com_ptr_t
.tlb dosyalarından sarmalayıcı sınıfları oluştururken kullandığı akıllı işaretçi türünü de kullanabilirsiniz. ATL üstbilgi dosyalarını eklemek istemediğinizde en iyi seçenektir.
CComPtr Sınıfı
ATL kullanabiliyorsanız bunu kullanın. ve AddRef
yöntemlerini kullanarak Release
başvuru sayımı gerçekleştirir. Daha fazla bilgi için bkz . Nasıl yapılır: CComPtr ve CComQIPtr Örnekleri Oluşturma ve Kullanma.
CComQIPtr Sınıfı
Benzerdir CComPtr
ancak COM nesnelerinde çağırmak QueryInterface
için basitleştirilmiş söz dizimi de sağlar. Daha fazla bilgi için bkz . Nasıl yapılır: CComPtr ve CComQIPtr Örnekleri Oluşturma ve Kullanma.
CComHeapPtr Sınıfı
Belleği boşaltmak için kullanılan CoTaskMemFree
nesnelere akıllı işaretçi.
CComGITPtr Sınıfı
Genel arabirim tablosundan (GIT) alınan arabirimler için akıllı işaretçi.
_com_ptr_t Sınıfı
İşlevselliğe CComQIPtr
benzer, ancak ATL üst bilgilerine bağımlı değildir.
POCO nesneleri için ATL akıllı işaretçileri
ATL, COM nesneleri için akıllı işaretçilere ek olarak, düz eski C++ nesneleri (POCO) için akıllı işaretçileri ve akıllı işaretçi koleksiyonlarını da tanımlar. Klasik Windows programlamada bu türler, özellikle kod taşınabilirliği gerekli olmadığında veya C++ Standart Kitaplığı ile ATL'nin programlama modellerini karıştırmak istemediğinizde C++ Standart Kitaplığı koleksiyonlarına yararlı alternatiflerdir.
CAutoPtr Sınıfı
Sahipliği bir kopyaya aktararak benzersiz sahipliği zorlayan akıllı işaretçi. Kullanım dışı bırakılan std::auto_ptr
Sınıfla karşılaştırılabilir.
CHeapPtr Sınıfı
C malloc işlevi kullanılarak ayrılan nesneler için akıllı işaretçi.
CAutoVectorPtr Sınıfı
kullanılarak new[]
ayrılan diziler için akıllı işaretçi.
CAutoPtrArray Sınıfı
Bir öğe dizisini CAutoPtr
kapsülleyen sınıf.
CAutoPtrList Sınıfı
Düğüm listesini CAutoPtr
işlemek için yöntemleri kapsülleyen sınıf.