2017-05-23 25 views
10

Aşağıdaki kod parçacığı için, yöntemlerde farklı başvuru sayıları gösterir. Birisi bu değerlerin neden farklı olduğunu açıklayabilir mi?Neden const shared_ptr <const T> & const shared_ptr <T> & farklı referans sayıları gösteriliyor?

class Foo { 
}; 

void f1(const std::shared_ptr<Foo>& ptr) { 
    std::cout << "f1(): counts: " << ptr.use_count() << std::endl; 
} 

void f2(const std::shared_ptr<const Foo>& ptr) { 
    std::cout << "f2(): counts: " << ptr.use_count() << std::endl; 
} 

int main() { 
    std::shared_ptr<Foo> ptr(new Foo); 
    std::cout << "main(): counts: " << ptr.use_count() << std::endl; 

    f1(ptr); 
    f2(ptr); 

    std::cout << "main(): counts: " << ptr.use_count() << std::endl; 

    return 0; 
} 

gelen çıkış: std::shared_ptr<Foo> ve std::shared_ptr<const Foo> farklı olduğu

main(): counts: 1 
f1(): counts: 1 
f2(): counts: 2 
main(): counts: 1 
+2

Muhtemelen f2 çağrısının, shared_ptr 'dan shared_ptr 'a dönüştürülmesinin bir parçası olarak örtülü bir geçici nesne oluşturması gerekiyordu ve bu, ikinci yeniden sayımın, f2 yürütüldüğü zaman geldiği yerdir. –

+0

Teşekkürler! Mantıklı olmak. –

+5

Hiç ilgili değil, sadece FYI: [new 'yerine make_shared' kullanmalısınız] (https://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/) – Tas

cevap

11

Not (farklı şablon tipi argümanları ile, yani Sınıf şablonu örneklemi farklı tipleri vardır).

geçmek zaman ptr (yani, bir std::shared_ptr<Foo>) f2 için, doğrudan std::shared_ptr<const Foo> için referans bağlı olamaz; Geçici bir std::shared_ptr<const Foo>'un oluşturulması ve daha sonra ptr parametresine bağlanması gerekir. Orijinal shared_ptr ile oluşturulan shared_ptr hisse sahipliğini, dolayısıyla use_count f2() içinde 2 için artırıldı.

f2(ptr); sona erdiğinde geçici olarak imha edilecek; daha sonra use_count 1'a düşürülür.

+0

üzerinde hiçbir kovaryansa sahip olmamasıdır, ilklendirmeyi 'std :: shared_ptr ptr (yeni Foo) olarak değiştirdim ve' f2 (ptr) 'olarak adlandırılır. Şimdi refcount'un artmadığını görebiliyorum. Çok beğeni! –

+0

@ArupRatonRoy Evet, bu durumda geçici bir sorun çıkarmaz. – songyuanyao