2008-09-26 34 views
76

Kodumda kapsamlı olarak boost:shared_ptr kullanıyorum. Aslında, yığın üzerinde tahsis edilen nesnelerin çoğu, bir shared_ptr tarafından tutulur. Ne yazık ki bu, this'u shared_ptr alan tüm işlevlere geçiremediğim anlamına gelir. Bu kodu göz önünde bulundurun: Burada iki sorun vardır. İlk olarak, bu derleme yapmaz çünkü shared_ptr için T * kurucusu açıktır. İkincisi, bar(boost::shared_ptr<Foo>(this)) ile oluşturmaya zorlarsam, nesneme ikinci bir paylaşımlı işaretçi yaratacağım ve sonunda bir çift silmeye yol açacağım.Bu destek için bir destek :: shared_ptr alma

Bu soru bana şu soruyu getiriyor: Var olan ortak bir işaretçinin kopyasını almak için herhangi bir standart desen var mı? Burada tek seçeneğimi saymak intrusive referans kullanıyor mu?

+0

"müdahaleci başvuru buraya benim tek seçenek sayma kullanarak _Is _ "Bu seçenekte sorun nedir? – curiousguy

+0

Belki de hiçbir şey. Durumunuza göre değişir. Nesnelerinizi büyütür ve smartpointer'leri tuttuğunuz sınıflar üzerinde kontrole sahip olmadığınız yerlerde çalışmayabilir. –

+0

enabe_shared_from_this std 'artık ::'. Cevabıma bir bak. –

cevap

102

Sen enable_shared_from_this türetebileceğimiz işaretleyin ve "bu" Kendi kendine nesnesine paylaşılan işaretçi yumurtlamaya yerine "() shared_from_this" kullanabilirsiniz sahiptir. linkte

Örnek:

#include <boost/enable_shared_from_this.hpp> 

class Y: public boost::enable_shared_from_this<Y> 
{ 
public: 

    shared_ptr<Y> f() 
    { 
     return shared_from_this(); 
    } 
} 

int main() 
{ 
    shared_ptr<Y> p(new Y); 
    shared_ptr<Y> q = p->f(); 
    assert(p == q); 
    assert(!(p < q || q < p)); // p and q must share ownership 
} 

Bu üye işlevinden yumurtlama ipler artırmak için iyi bir fikirdir :: Bir shared_from_this bağla var() yerine bu. Nesnenin serbest bırakılmamasını sağlayacaktır.

+0

f() gibidir ".copy()" ve aynı zamanda sığ bir kopyasıdır. –

9

Gerçekten pFoo iç çubuğunun daha fazla paylaşılan kopyasını yapıyor musunuz? İçinde deli bir şey yapmıyoruz, sadece bunu:


void bar(Foo &foo) 
{ 
    // ... 
} 
3
bir işaretçi kabul işlevi yapmak istiyor

iki davranışlardan biri:

  • nesne, geçirilen Sahibi ve kapsam dışı olduğunda silin. Bu durumda, X * 'i kabul edip hemen o nesnenin etrafına bir scoped_ptr sarın (işlev gövdesinde). Bu, "bu" ya da genel olarak, herhangi bir yığın-ayrılmış nesne kabul etmek için çalışacaktır.
  • paylaş bir işaretçi (Sahibi olmadığım) nesneye geçirilen. Bu durumda yapmanız değil en nesneyi silmek istemiyorum çünkü hiç bir scoped_ptr kullanmak istiyorum Fonksiyonunuzun sonu. Bu durumda, teorik olarak istediğiniz şey bir shared_ptr'dir (ona başka bir yerde linked_ptr denir). Destek kütüphanesi a version of shared_ptr, ve bu da Scott Meyers'ın C++ kitabında (3. baskıda 18. öğe) tavsiye edilir.

Düzenleme: Oops Biraz soruyu yanlış okumuş ve şimdi bu cevabı tam soruyu ele değil bakın. Benzer kod üzerinde çalışan herkes için yararlı olabileceğinden, yine de bırakacağım.

19

Sadece shared_ptr yerine işlev parametreniz için bir ham işaretçiyi kullanın. Akıllı bir işaretçinin amacı, nesnenin kullanım ömrünü kontrol etmektir, ancak nesnenin kullanım ömrü C++ kapsam kuralları ile garanti edilmiştir: en azından işlevinizin sonuna kadar var olacaktır.Yani, çağıran kod, işlev döndürmeden önce nesneyi silemez; Böylece, "aptal" işaretçisinin güvenliği, işlevinizin içindeki nesneyi silmeye çalışmadığınız sürece garanti edilir. Eğer pointer bir kopyasını yapmak için işlevini işlevine nesnenin sahipliğini geçmesi veya istemek istediğinizde

bir fonksiyonun içine Shared_ptr geçmesi gereken tek zamandır. C++ 11 shared_ptr ve enable_shared_from_this ile

+1

Anlaşmalı. Birçok kez foo (const Object * object_ptr) {} foo (obj.get()); obj bir destek kaynağıdır :: shared_ptr < Object >. Herb Sutter için web üzerinde arama musunuz, bir bu ve benzeri konular hakkında bazı büyük bilgi var bir başka ve makale yazar. –

+1

sen daha iyi IMO olduğu başvuru kullanabilirsiniz ardından işaretçi, (büyük olasılıkla) kullanabiliyorsa O ... konuyla ilgisi küçük ama. –

+1

@ denis-bu, bir 'NULL' işaretçisi olduğunda bir olasılıktır. Ama iyi bir nokta çiziyorsun. –

5

standart kitaplığı artık. İkincisi, isminden de anlaşılacağı gibi, bu dava için tam olarak. yukarıdaki bağlantılarda bu konuda

http://en.cppreference.com/w/cpp/memory/shared_ptr

http://en.cppreference.com/w/cpp/memory/enable_shared_from_this

Örnek bazlar:

struct Good: std::enable_shared_from_this<Good>{ 
    std::shared_ptr<Good> getptr() { 
     return shared_from_this(); 
    } 
}; 

kullanım:?

std::shared_ptr<Good> gp1(new Good); 
std::shared_ptr<Good> gp2 = gp1->getptr(); 
std::cout << "gp2.use_count() = " << gp2.use_count() << '\n'; 
İlgili konular