C ++ 03
std::auto_ptr
- Belki de ilk taslak sendromundan muzdarip olan orijinallerden biri yalnızca sınırlı çöp toplama olanağı sağlıyor. İlk dezavantajı, delete
diziye tahsis edilmiş nesneleri ( new[]
) tutmak için onları yok etmeye çağırmasıdır . İşaretçinin sahipliğini alır, böylece iki otomatik işaretçi aynı nesneyi içermemelidir. Atama, sahipliği aktaracak ve rvalue otomatik işaretçisini bir boş göstericiye sıfırlayacaktır . Bu belki de en kötü dezavantaja yol açar; Yukarıda belirtilen kopyalanamama nedeniyle STL kaplarında kullanılamazlar. Herhangi bir kullanım senaryosuna son darbe, bir sonraki C ++ standardında kullanımdan kaldırılmalarıdır.
std::auto_ptr_ref
- Bu akıllı bir işaretçi değildir, aslında std::auto_ptr
belirli durumlarda kopyalama ve atamaya izin vermek için birlikte kullanılan bir tasarım detayıdır . Özellikle, mülkiyeti devretmek için bir hareket oluşturucu olarak da bilinen Colvin-Gibbons hilesini kullanarak const olmayan std::auto_ptr
bir değere dönüştürmek için kullanılabilir .
Aksine, belki de std::auto_ptr
otomatik çöp toplama için genel amaçlı bir akıllı işaretçi olarak kullanılmak üzere tasarlanmamıştı. Sınırlı anlayışımın ve varsayımlarımın çoğu, Herb Sutter'ın auto_ptr'nin Etkili Kullanımına dayanmaktadır ve her zaman en optimize şekilde olmasa da düzenli olarak kullanıyorum.
C ++ 11
std::unique_ptr
- Dizilerle çalışma, özel kopya oluşturucu aracılığıyla ldeğer koruması, STL kapsayıcıları ve algoritmaları ile kullanılabilir olma gibi std::auto_ptr
zayıflıkları düzeltmek için temel iyileştirmeler dışında, onu değiştirecek olan arkadaşımız oldukça benzer olacaktır . Performans ek yükü olduğundan ve bellek ayak izi sınırlıdır bu, ham işaretçileri değiştirmek için ideal bir adaydır veya belki de daha uygun bir şekilde sahip olmak olarak tanımlanır. "Benzersiz" ifadesinin ima ettiği gibi, önceki gibi işaretçinin yalnızca bir sahibi vardır .std::auto_ptr
std::auto_ptr
std::shared_ptr
- Bunun TR1'e dayandığına ve boost::shared_ptr
takma ad ve işaretçi aritmetiğini de içerecek şekilde geliştirildiğine inanıyorum . Kısacası, dinamik olarak tahsis edilmiş bir nesnenin etrafına referans sayılan akıllı işaretçiyi sarar. "Paylaşılan" ifadesi, son paylaşılan işaretçinin son referansı kapsam dışına çıktığında işaretçinin birden fazla paylaşılan işaretçiye ait olabileceğini ima ettiğinden, nesne uygun şekilde silinecektir. Bunlar ayrıca iş parçacığı açısından güvenlidir ve çoğu durumda eksik türleri işleyebilir. varsayılan ayırıcı kullanılarak tek bir yığın tahsisi ile std::make_shared
verimli bir şekilde oluşturmak için kullanılabilir std::shared_ptr
.
std::weak_ptr
- Aynı şekilde TR1 ve boost::weak_ptr
. Bu, a'nın sahip olduğu bir nesneye bir referanstır std::shared_ptr
ve bu nedenle std::shared_ptr
referans sayısı sıfıra düşerse nesnenin silinmesini engellemeyecektir . Ham işaretçiye erişmek için önce , sahip olunan işaretçinin süresi dolmuşsa ve zaten yok edilmişse boş bir döndüren std::shared_ptr
by çağrıya erişmeniz gerekir . Bu, birden çok akıllı işaretçi kullanırken belirsiz asılı referans sayılarından kaçınmak için öncelikle kullanışlıdır.lock
std::shared_ptr
artırmak
boost::shared_ptr
- Muhtemelen en çeşitli senaryolarda (STL, PIMPL, RAII, vb.) Kullanımı en kolay olan bu, paylaşılan referanslı sayılan akıllı işaretçidir. Bazı durumlarda performans ve ek yük hakkında birkaç şikayet duydum, ancak bunları görmezden gelmiş olmalıyım çünkü tartışmanın ne olduğunu hatırlayamıyorum. Görünüşe göre, beklemede olan bir standart C ++ nesnesi olacak kadar popülerdi ve akıllı işaretçilerle ilgili norm üzerinde hiçbir dezavantaj akla gelmiyor.
boost::weak_ptr
- std::weak_ptr
Bu uygulamaya dayalı olarak, önceki açıklamaya benzer şekilde , bu, bir boost::shared_ptr
. Şaşırtıcı bir şekilde lock()
"güçlü" paylaşılan işaretçiye erişmek için çağrı yapmazsınız ve zaten yok edilmiş olabileceği için geçerli olduğundan emin olmak için kontrol etmeniz gerekir. Döndürülen paylaşılan işaretçiyi saklamadığınızdan emin olun ve işiniz biter bitmez kapsam dışına çıkmasına izin verin, aksi takdirde referans sayılarınızın takılacağı ve nesnelerin yok edilmeyeceği döngüsel referans problemine geri dönersiniz.
boost::scoped_ptr
- Bu, muhtemelen boost::shared_ptr
kullanılabildiğinde daha iyi performans gösteren bir alternatif için tasarlanmış, az ek yükü olan basit bir akıllı işaretçi sınıfıdır . std::auto_ptr
Özellikle bir STL kabının bir öğesi olarak veya aynı nesneye birden çok işaretçi ile güvenli bir şekilde kullanılamaması gerçeğiyle karşılaştırılabilir .
boost::intrusive_ptr
- Bunu hiç kullanmadım ama benim anlayışıma göre, kendi akıllı işaretçi uyumlu sınıflarınızı oluştururken kullanılmak üzere tasarlandı. Referans sayımını kendiniz uygulamanız gerekir, ayrıca sınıfınızın genel olmasını istiyorsanız birkaç yöntemi uygulamanız gerekir, ayrıca kendi iş parçacığı güvenliğinizi uygulamanız gerekir. Artı tarafta, bu muhtemelen size tam olarak ne kadar veya ne kadar "akıllılık" istediğinizi seçmenin ve seçmenin en özel yolunu verir. intrusive_ptr
genellikle shared_ptr
nesne başına tek bir yığın tahsisine sahip olmanıza izin verdiğinden daha verimlidir . (teşekkürler Arvid)
boost::shared_array
- Bu boost::shared_ptr
diziler için. Temel olarak new []
, operator[]
ve tabii ki delete []
içinde pişirilir. Bu STL kaplarında kullanılabilir ve bildiğim kadarıyla her şeyi boost:shared_ptr
yapar, ancak bunlarla kullanamasanız boost::weak_ptr
da. Bununla birlikte, alternatif boost::shared_ptr<std::vector<>>
olarak benzer işlevler için ve boost::weak_ptr
referanslar için kullanma yeteneğini yeniden kazanmak için bir kullanabilirsiniz .
boost::scoped_array
- Bu boost::scoped_ptr
diziler için. Gibi boost::shared_array
tüm gerekli dizi iyilik pişirilir. Bu olmayan bir copyable ve böylece STL kaplarda kullanılamaz. Neredeyse her yerde kendinizi bunu kullanmak isterken buldum, muhtemelen kullanabileceksiniz std::vector
. Hangisinin gerçekte daha hızlı veya daha az ek yüke sahip olduğunu asla belirlemedim, ancak bu kapsamlı dizi bir STL vektöründen çok daha az ilgili görünüyor. Yığın üzerinde tahsis tutmak istediğinizde boost::array
bunun yerine düşünün .
Qt
QPointer
- Qt 4.0'da tanıtılan bu, yalnızca QObject
sınıflarla çalışan ve türetilen sınıflarla çalışan "zayıf" bir akıllı göstericidir , Qt çerçevesinde neredeyse her şeydir, bu yüzden bu gerçekten bir sınırlama değildir. Bununla birlikte, "güçlü" bir işaretçi sağlamaması gibi sınırlamalar vardır ve temeldeki nesnenin geçerli olup olmadığını kontrol edebilmenize rağmen, isNull()
özellikle çok iş parçacıklı ortamlarda bu denetimi geçtikten hemen sonra nesnenizin yok edildiğini görebilirsiniz. Qt insanlar inanıyorum ki bunun kullanımdan kaldırıldığını düşünüyor.
QSharedDataPointer
- Bu, boost::intrusive_ptr
bazı yerleşik iş parçacığı güvenliğine sahip olmasına rağmen, potansiyel olarak karşılaştırılabilir "güçlü" bir akıllı işaretçidir, ancak alt sınıflandırma yoluyla yapabileceğiniz referans sayma yöntemlerini ( ref
ve deref
) eklemenizi gerektirir QSharedData
. Qt'nin çoğunda olduğu gibi, nesneler en iyi şekilde geniş kalıtım yoluyla kullanılır ve her şeyin alt sınıflara ayrılması amaçlanan tasarım gibi görünür.
QExplicitlySharedDataPointer
- QSharedDataPointer
Örtük olarak çağırmaması dışında çok benzer detach()
. Bu sürüm 2.0'ı QSharedDataPointer
, referans sayısı sıfıra düştükten sonra tam olarak ne zaman ayrılacağına dair kontroldeki hafif artış, özellikle yepyeni bir nesneye değmez diye adlandırıyorum.
QSharedPointer
- Atomik referans sayma, iş parçacığı güvenli, paylaşılabilir işaretçi, özel silmeler (dizi desteği), akıllı bir işaretçinin olması gereken her şey gibi sesler. Bu, Qt'de öncelikle akıllı bir işaretçi olarak kullandığım şeydir ve bunu boost:shared_ptr
, Qt'deki birçok nesne gibi muhtemelen önemli ölçüde daha fazla ek yük ile karşılaştırılabilir buluyorum .
QWeakPointer
- Tekrarlayan bir model hissediyor musunuz? Tıpkı std::weak_ptr
ve boost::weak_ptr
bu, QSharedPointer
iki akıllı işaretçi arasında, aksi takdirde nesnelerinizin asla silinmemesine neden olacak referanslara ihtiyaç duyduğunuzda kullanılır .
QScopedPointer
- Bu ad da tanıdık gelmeli ve aslında boost::scoped_ptr
paylaşılan ve zayıf işaretçilerin Qt sürümlerinden farklı olarak temel almalıdır . Ek yükü olmadan tek bir sahipli akıllı işaretçi sağlama işlevi görür ve QSharedPointer
bu da onu uyumluluk, istisnai güvenli kod ve kullanabileceğiniz std::auto_ptr
veya kullanabileceğiniz her şey için daha uygun hale getirir boost::scoped_ptr
.