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.
Tip
AddRef/Release'ı otomatikleştirmek için akıllı işaretçileri kullanın. El ile başvuru sayımı hataya açıktır. Modern C++ COM kodu, ve otomatik olarak çağıran AddRefRelease akıllı işaretçiler kullanmalıdır:
| Akıllı işaretçi | Library | Ne zaman kullanılır? |
|---|---|---|
Microsoft::WRL::ComPtr<T> |
Windows runtime C++ Şablon Kütüphanesi (WRL) | C++ dilinde WinRT ve klasik COM |
winrt::com_ptr<T> |
C++/WinRT | C++/WinRT projeleri (yeni kod için tercih edilir) |
wil::com_ptr<T> |
uygulama kitaplıklarını Windows | Herhangi bir C++ COM kodu; günlüğe kaydetme ve tanılama ekler |
ATL::CComPtr<T> |
Atlanta Havalimanı | Eski ATL projeleri (yeni kod kullanmaktan kaçının) |
// ✅ Smart pointer — Release is called automatically at end of scope
winrt::com_ptr<IStream> stream;
HRESULT hr = CreateStreamOnHGlobal(nullptr, TRUE, stream.put());
// ❌ Raw pointer — easy to leak on early return or exception
IStream* pStream = nullptr;
hr = CreateStreamOnHGlobal(nullptr, TRUE, &pStream);
// ... if any code path forgets pStream->Release(), you have a leak
Ham işaretçilerle, eski C koduyla çalışırken veya COM nesnelerini dahili olarak uyguladığınızda aşağıdaki el ile IUnknown* uygulanan kurallar geçerli olmaya devam eder.
Bir nesnenin ömrünü yönetmek için başvuru sayısı kullanmak, birden çok istemcinin nesnenin ömrünü yönetirken birbirleriyle koordine olmak zorunda kalmadan tek bir nesneye erişim elde etmesine ve serbest bırakmasına olanak tanır. İstemci nesnesi belirli kullanım kurallarına uygun olduğu sürece, nesne bu yönetimi sağlar. Bu kurallar, nesneler arasındaki başvuruların nasıl yönetileceğini belirtir. (BU kurallar bir nesne içindeki ilke için makul bir başlangıç noktası olsa da, COM nesnelerin iç uygulamalarını belirtmez.)
Kavramsal olarak, arabirim işaretçileri, arabirim işaretçisini tutan tüm iç hesaplama durumunu içeren işaretçi değişkenleri içinde barındırıyor olarak düşünülebilir. Bu, bellek konumlarındaki, iç işlemci kayıtlarındaki değişkenleri ve hem programcı tarafından oluşturulan hem de derleyici tarafından oluşturulan değişkenleri içerir. İşaretçi değişkenine atama veya bu değişkenin başlatılması, zaten var olan bir işaretçinin yeni bir kopyasını oluşturmayı içerir. Bir değişkende işaretçinin bir kopyasının bulunduğu (atama/başlatmada kullanılan değer), şimdi iki tane vardır. İşaretçi değişkenine atama, değişkenin kendisinin yok edilmesi gibi, değişkende şu anda işaretçi kopyasını yok eder. (Yani, yığın çerçevesi gibi değişkenin bulunduğu kapsam yok edilir.)
COM istemcisinin perspektifinden bakıldığında, her arabirim için her zaman başvuru sayımı yapılır. İstemciler hiçbir zaman bir nesnenin tüm arabirimler için aynı sayacı kullandığını varsaymamalıdır.
Varsayılan durum, arabirim işaretçisinin her yeni kopyası için AddRef çağrılması ve aşağıdaki kuralların aksini izin vermesi dışında arabirim işaretçisinin her yok edilmesi için Yayın çağrılması gerektiğidir:
- İşlevlere yönelik yerleşik parametreler. Dış değer üzerinde depolandığında uygulama kodunda serbest bırakılacağından (Releaseçağrısıyla) çağıranın parametresinde AddRef çağırması gerekir.
- Genel değişken getiriliyor. Genel değişkende işaretçinin var olan bir kopyasından arabirim işaretçisinin yerel kopyasını oluştururken, yerel kopya hala geçerliyken başka bir işlev genel değişkendeki kopyayı yok ettiğinden yerel kopyada AddRef çağırmalısınız.
- "İnce havadan" sentezlenen yeni işaretçiler Bir arabirim işaretçisini başka bir kaynaktan almak yerine özel iç bilgi kullanarak sentezleyen bir işlev, başlangıçta yeni sentezlenen işaretçide AddRef çağırmalıdır. Bu tür yordamlara örnek oluşturma yordamları, QueryInterfaceuygulamaları vb. örnek verilebilir.
- Dahili olarak depolanan bir işaretçinin kopyasını alma. İşlev, çağrılan nesne tarafından dahili olarak depolanan bir işaretçinin kopyasını aldığında, bu nesnenin kodu işlev döndürülmeden önce işaretçide AddRef çağırmalıdır. İşaretçi alındıktan sonra, kaynak nesnenin yaşam süresiyle işaretçinin dahili olarak depolanan kopyası arasındaki ilişkiyi belirlemenin başka bir yolu yoktur.
Varsayılan durumun tek özel durumları, yönetici kodun bir nesnedeki aynı arabirime yönelik bir işaretçinin iki veya daha fazla kopyasının yaşam sürelerinin ilişkilerini bilmesini ve yalnızca başvuru sayısının sıfıra gitmesine izin vererek nesnenin yok edilmediğinden emin olmasını gerektirir. Genellikle aşağıdaki gibi iki durum vardır:
- bir işaretçinin bir kopyası zaten var olduğunda ve ikinci bir kopya daha sonra oluşturulduğunda ve ilk kopya hala mevcutken yok edildiğinde, AddRef ve ikinci kopya için Release çağrıları atlanabilir.
- bir işaretçinin bir kopyası mevcut olduğunda ve ikinci bir kopya oluşturulduğunda ve ikinci kopyadan önce ilki yok edildiğinde, ikinci kopya için AddRef ve ilk kopya için Yayın çağrıları atlanabilir.
İlk ikisi özellikle yaygın olan bu durumlara özel örnekler aşağıda verilmiştir:
- İşlevlere yönelik parametrelerde. Bir işleve parametre olarak geçirilen arabirim işaretçisinin kopyasının ömrü, değeri başlatmak için kullanılan işaretçininkiyle iç içe yerleştirilmiştir, bu nedenle parametrede ayrı bir başvuru sayısına gerek yoktur.
- dönüş değerleri de dahil olmak üzere işlevlerden parametreler çıkar. out parametresini ayarlamak için işlev, arabirim işaretçisinin kararlı bir kopyasına sahip olmalıdır. Dönüşte, işaretçiyi serbest bırakmak çağıran sorumludur. Bu nedenle out parametresinin ayrı bir başvuru sayısına ihtiyacı yoktur.
- Yerel değişkenler. Yöntem uygulaması, yığın çerçevesinde ayrılan işaretçi değişkenlerinin her birinin yaşam sürelerini denetler ve AddRef/ çiftlerinin yedekliatlanmasını belirlemek için bunu kullanabilir.
- Arka uç noktaları. Bazı veri yapıları, her birinin diğerini işaret eden iki nesne içerir. İlk nesnenin ömrünün ikinci nesnenin yaşam süresini içerdiği biliniyorsa, ikinci nesnenin işaretçisinde ilk nesneye yönelik bir başvuru sayısı olması gerekmez. Bu döngüden kaçınmak genellikle uygun serbest bırakma davranışının korunmasında önemlidir. Ancak, işletim sisteminin uzaktan işlemeyi işleyen bölümünün bu ilişkiyi bilmesi mümkün olmadığından, sayılmamış işaretçiler çok dikkatli kullanılmalıdır. Bu nedenle, hemen hemen her durumda, ilk işaretçinin ikinci bir "arkadaş" nesnesinin (bu nedenle döngüsellikten kaçınma) arka noktasının görmesi tercih edilen çözümdür. ÖRNEĞIN COM'un bağlanabilir nesneler mimarisi bu yaklaşımı kullanır.
Başvuru sayılan nesneleri uygularken veya kullanırken, bir işlevin işlenmesi sırasında nesne kararlılığını garanti eden yapay başvuru sayısınıuygulamak yararlı olabilir. Bir arabirimin yöntemini uygularken, başvuru sayınızı bir nesneye azaltma şansı olan işlevleri çağırarak nesnenin erken serbest bırakılmasına ve uygulamanın başarısız olmasına neden olabilirsiniz. Bunu önlemenin sağlam bir yolu, yöntem uygulamasının başında AddRef çağrısı eklemek ve bunu yöntem döndürülmeden hemen önce Release çağrısıyla eşleştirmektir.
Bazı durumlarda, AddRef ve Release dönüş değerleri kararsız olabilir ve bu değerlere güvenilmemelidir; yalnızca hata ayıklama veya tanılama amacıyla kullanılmalıdır.
İlgili konular
-
Başvuru Sayma Aracılığıyla Nesne YaşamLarını Yönetmeyi