C make_shared ve normal shared_ptr farkı
std::shared_ptr<Object> p1 = std::make_shared<Object>("foo");
std::shared_ptr<Object> p2(new Object("foo"));
Google ve stackoverflow birçok mesaj var bu konuda, ama make_shared
doğrudan shared_ptr
kullanarak daha verimli olduğunu anlamak mümkün değilim.
Birisi açıklasın bana make_shared
verimli nasıl anlamak mümkün olacak, böylece nesnelerin adım dizisi ve işlemleri her iki tarafından yapılan adım. Başvuru için yukarıda bir örnek verdim.
CEVAP
Fark std::make_shared
std::shared_ptr
kurucu çağırmak iki gerçekleştirir ise bir yığın ayırma gerçekleştirir.
Nerede yığın ayırma olur mu?
std::shared_ptr
iki varlık yönetir
- denetim bloğu (ref-sayar gibi mağazalarda meta verileri sildim türü deleter, vb)
- nesne yönetilen
std::make_shared
denetim bloğu hem de veri alanı için gerekli yığın ayırma tek bir muhasebe yapar. Diğer durumda, new Obj("foo")
çağırır bir yığın ayırma yönetilen veri ve std::shared_ptr
yapıcı denetim bloğu için de bir tane yapar.
Daha fazla bilgi için, check outUygulama Notlarıcppreference.
Güncelleme: Durum-Güvenlik
OP şeyler hariç-güvenlik tarafı merak gibi görünüyor beri, ben cevabımı güncelledik.
Bu örneği ele alalım
void F(const std::shared_ptr<Lhs> &lhs, const std::shared_ptr<Rhs> &rhs) { /* ... */ }
F(std::shared_ptr<Lhs>(new Lhs("foo")),
std::shared_ptr<Rhs>(new Rhs("bar")));
C iç ifadelerin değerlendirilmesi keyfi sipariş verir, çünkü, olası bir sipariş
new Lhs("foo"))
new Rhs("bar"))
std::shared_ptr<Lhs>
std::shared_ptr<Rhs>
Şimdi, bir istisna adım 2 (örn. atılan etsek bellek istisna, Rhs
yapıcı bazı özel durum gönderdi). Biz o zaman hafıza 1, hiçbir şey beri bunu temizlemek için bir şansa sahip olacaktır adımda tahsis kaybedersiniz. Sorunun esası burada ham işaretçi std::shared_ptr
kurucusuna hemen geçti alamadım.
Bunu düzeltmek için tek yol bu keyfi sipariş gerçekleştirilemiyor böylece ayrı satırlarda bunları yapmak için.
auto lhs = std::shared_ptr<Lhs>(new Lhs("foo"));
auto rhs = std::shared_ptr<Rhs>(new Rhs("bar"));
F(lhs, rhs);
Tabii ki bunu çözmek için tercih edilen yolu std::make_shared
yerine kullanmaktır.
F(std::make_shared<Lhs>("foo"), std::make_shared<Rhs>("bar"));
Güncelleme II: std::make_shared
Dezavantajı
Casey'in sözleri: . alıntı
Tek bir ayırma var bu yana, pointee belleği kontrol bloğu artık kullanımda kadar kaldırıldı edilemez.
weak_ptr
bir denetim bloğu kadar hayatta kalabilir.
Neden weak_ptr
s örneklerini kontrol bloğu canlı tutmak mı?
weak_ptr
ler için bir şekilde yönetilen nesne hala geçerli olup olmadığını belirlemek için (örn. olmalı lock
). Kontrol bloğunda saklanan ve yönetilen nesne, kendi shared_ptr
s sayısını kontrol ederek bunu yapıyorlar. Sonucu kontrol blokları shared_ptr
sayısı kadar canlı ve weak_ptr
sayısı 0 hit hem de.
std::make_shared
geri
std::make_shared
tek bir kontrol bloğu ve yönetilen nesne için tahsisat yığın yapar, kontrol bloğu için bellek boşaltmak ve yönetilen bağımsız bir nesne yoktur. shared_ptr
s weak_ptr
s hayatta hiçbir kadar kontrol bloğu ve olur yönetilen nesne, her ikisi de özgür olana kadar beklemeliyiz.
Sanırım biz yerine yığın ayırma denetim bloğu için iki gerçekleştirilen ve new
shared_ptr
ile yönetilen nesne oluşturucu. O zaman biz boş bellek için yönetilen nesne (belki daha erken) yok shared_ptr
s hayatta ve boş bellek için kontrol bloğu (belki daha sonra) yok weak_ptr
s hayatta.
Var ile tüm olumsuzlukları bir shared_...
Uygulanmadan önce normal ifade desenle...
PHP PDO vs normal mysql_connect...
Nasıl Dijkstra'in Algoritma ve Yı...
Normal bir ifade geçerli bir normal if...