2014-09-18 17 views
69

cplusplus.com shared_ptr page bir boşstd::shared_ptr ve boşshared_ptr arasında bir ayrım çağırır. cppreference.com page açıkça ayırt edemez, ancak std::shared_ptr davranışında "boş" ve nullptr ile karşılaştırma kullanır.C++ 'da boş ve boş bir std :: shared_ptr arasındaki fark nedir?

Boş ve sıfır shared_ptr arasında bir fark var mı? Bu karışık davranış işaretçileri için herhangi bir kullanım durumu var mı? Boş olmayan boş bir shared_ptr bile anlamlı mı? Normal kullanımda (yani, açıkça bir tane oluşturmadıysanız) bir boş-ama-olmayan-null shared_ptr ile sonuçlanabilecek bir durum olur mu?

C++ 11 sürümü yerine Boost sürümünü kullanıyorsanız, bu yanıtlardan herhangi birini değiştirin?

cevap

72

shared_ptr davranışının garip bir köşesi. Bu şey ve başka şeye puan sahibi bir shared_ptr emin olmak için izin veren bir Oluşturucu sahip: için

template< class Y > 
shared_ptr(const shared_ptr<Y>& r, T *ptr); 
shared_ptr r ile bu yapıcı hisse sahipliğini kullanılarak inşa

ancak puan ne olursa olsun ptr noktaları (yani, get() veya operator->() numaralarını arayarak ptr döndürecektir). Bu, ptr'un r'a ait nesnenin bir alt nesnesine (ör., Bir veri üyesi) işaret ettiği durumlar için kullanışlıdır. Bağlı

sayfa hiçbir şey boş sahibi bir shared_ptr çağırır ve hiçbir şey işaret eden bir shared_ptr (yani kimin get() == nullptr) boş. (Boş bu anlamda standart olarak kullanılmaktadır; null değil.) Boş olmayan boş bir shared_ptr yapılandırabilirsiniz, ancak çok kullanışlı olmayacaktır. Bir boş-değil-null shared_ptr temelde, passing a pointer to something allocated on the stack to a function expecting a shared_ptr gibi bazı garip şeyler yapmak için kullanılabilecek bir sahip olmayan işaretçidir (ancak ilk önce shared_ptr'u API'nin içine koyduğunda delmeyi öneririm). onlar örtüşme yapıcısı diyoruz

boost::shared_ptr da has this constructor.

+7

değer olmayan boş boş shared_ptr nesnenin türüne (değil nullptr) Burada

sıfır işaretçi ile inşa edilebilir örneğidir: ** C++ 11 § 20.7.2.2.1 (p16) ** "Not: Bu kurucu boş olmayan bir" shared_ptr "örneğinin NULL olmayan bir saklı işaretçiye sahip olmasını sağlar." Ayrıca, önceki notu (p15) belirtmeye değmez, "Sarkma işaretçisinin olasılığını önlemek için, bu kurucunun kullanıcısı," r "nin sahiplik grubu yok edilinceye kadar" p "nin geçerli kalmasını sağlamalıdır. Gerçekten nadiren kullanılan bir yapı. – WhozCraig

+0

@Cubbi A 'shared_ptr',' get() ',' nullptr' * döndürür *, bir şeyin sahibi olup olmadığına bakılmaksızın nullptr öğesine eşittir. –

+3

Null-ama-nonempty 'shared_ptr's *, * işlevler, sahip tüm işaretçiler kapsam dışına çıktığında (bir istisna durumunda bile!) Yürütüldüğünden emin olmak için yararlı olabilir. Emin, şimdi bunun için özel bir sınıf var mı. – coldfix

2

Boş ve boş paylaşılan_ptr arasında fark var mı?

Boş shared_ptr denetim bloğu ve boş shared_ptr 0. Kopya olarak kabul kullanımı sayımı başka boş shared_ptr olduğunu bulunmamaktadır. Her ikisi de ortak denetim bloğunu paylaşmayan ayrı bir shared_ptr s'dir, çünkü sahip olmadıkları için. Boş shared_ptr, varsayılan kurucu ile veya nullptr alan yapıcı ile yapılandırılabilir.

Boş boş değerli shared_ptr, diğer shared_ptr s ile paylaşılabilen denetim bloğuna sahiptir.Boş olmayan boş shared_ptr kopyası shared_ptr yüzden kullanmak orijinal sayımı ile aynı kumanda bloğu paylaşan shared_ptr olduğunu Denilebilir değil 0. olduğunu shared_ptr pay aynı nullptr tüm kopyaları.

#include <iostream> 
#include <memory> 

int main() 
{ 
    std::cout << "std::shared_ptr<int> ptr1:" << std::endl; 
    { 
     std::shared_ptr<int> ptr1; 
     std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl; 
     std::shared_ptr<int> ptr2 = ptr1; 
     std::cout << "\tuse count after copying ptr: " << ptr1.use_count() << std::endl;   
     std::cout << "\tptr1 is " << (ptr1 ? "not null" : "null") << std::endl; 
    } 
    std::cout << std::endl; 

    std::cout << "std::shared_ptr<int> ptr1(nullptr):" << std::endl; 
    { 
     std::shared_ptr<int> ptr1(nullptr); 
     std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl; 
     std::shared_ptr<int> ptr2 = ptr1; 
     std::cout << "\tuse count after copying ptr: " << ptr1.use_count() << std::endl;   
     std::cout << "\tptr1 is " << (ptr1 ? "not null" : "null") << std::endl; 
    } 
    std::cout << std::endl; 

    std::cout << "std::shared_ptr<int> ptr1(static_cast<int*>(nullptr))" << std::endl; 
    { 
     std::shared_ptr<int> ptr1(static_cast<int*>(nullptr)); 
     std::cout << "\tuse count before copying ptr: " << ptr1.use_count() << std::endl; 
     std::shared_ptr<int> ptr2 = ptr1; 
     std::cout << "\tuse count after copying ptr: " << ptr1.use_count() << std::endl;   
     std::cout << "\tptr1 is " << (ptr1 ? "not null" : "null") << std::endl; 
    } 
    std::cout << std::endl; 

    return 0; 
} 

Bu çıktılar: not

std::shared_ptr<int> ptr1: 
    use count before copying ptr: 0 
    use count after copying ptr: 0 
    ptr1 is null 

std::shared_ptr<int> ptr1(nullptr): 
    use count before copying ptr: 0 
    use count after copying ptr: 0 
    ptr1 is null 

std::shared_ptr<int> ptr1(static_cast<int*>(nullptr)) 
    use count before copying ptr: 1 
    use count after copying ptr: 2 
    ptr1 is null 

http://coliru.stacked-crooked.com/a/54f59730905ed2ff

+0

Bu daha iyi yanıtlar niçin shared_ptr özel silme işleminde null'u kontrol etmemiz gerektiğini düşünüyorum. [Shared_ptr'nin özel olarak kaldırılmasında nullptr'i kontrol etmek mantıklı mı?] (Https://stackoverflow.com/questions/42962515/does-it-make-sense-to-check-for-nullptr-in-custom-deleter -of-paylaşılan ptr/42962962) –

İlgili konular