2016-03-17 15 views
10

Bu kod yapmak istediğim şudur:std :: move() öğesinden sonra unique_ptr'ye ne olur?

Tony& Movie::addTony() 
{ 
    std::unique_ptr<Tony> tony(new Tony); 
    attachActor(std::move(tony)); 
    return *tony.get(); 
} 

Ama *tony.get() aynı işaretçi veya boş olacaktır: Bunun yerine bu yapabileceğini merak ediyorum

Tony& Movie::addTony() 
{ 
    Tony *newTony = new Tony; 
    std::unique_ptr<Tony> tony(newTony); 
    attachActor(std::move(tony)); 
    return *newTony; 
} 

? Doğrulayabileceğimi biliyorum ama yapması gereken standart şey nedir?

+0

Neden '' unique_ptr 'öğesini 'attachActor()' ile başlayalım? AttachActor() 'aslında ne yapar? –

cevap

15

Hayır, bunu yerine yapamazsınız. unique_ptr taşınıyorsa onu boşver. Eğer yapmadıysa, o zaman eşsiz olmazdı. U (unique_ptr nesne) can, üzerine isteği transfer

attachActor(std::unique_ptr<Tony>&&) { 
    // take the unique_ptr by r-value reference, 
    // and then don't move from it, leaving the 
    // original intact 
} 

Bölüm 4.

Ayrıca 20.8.1 paragraf: Ben tabii attachActor Böyle aptal şey yapmaz varsayıyorum başka bir benzersiz işaretçinin sahiplik u2. kadar nullptr eşittir ve
-
     , u2.p transfer öncesi yukarı eşittir -
     : böyle bir transferi tamamlandıktan sonra, aşağıdaki Hedefşartlar tutun       - ön aktarım durumu devam ediyorsa, bu durum u2.d.'ye aktarılır.

+0

Olsa bile, 'unique_ptr &&' (hareket yapıcı ve hareket atamalarının yanı sıra) 'i alan bir işleve sahip olmak harika bir fikir değildir. – Rufflewind

+0

@Rufflewind: Agreed –

+0

@BenjaminLindley, cevap için teşekkürler! Evet, attachActor() std :: unique_ptr alır, hiçbir şey fantezi değildir. – user3496846

7

standart (  20.8.1.2.1 ¶   16, vurgu eklenmiştir §) std::unique_ptr

unique_ptr(unique_ptr&& u) noexcept; 

ait hareket yapıcı oluşturur söylüyor için u den sahipliğini aktararak tarafından unique_ptr*this.

Bu nedenle, sonra tony, tony artık nesne ve dolayısıyla tony.get() == nullptr sahibi senin oluşturacak attachActor için argüman olarak geçirilen geçici nesneyi taşımak-oluştururlar. (Bu, standart kitaplığın gerçekten taşınan bir nesnenin durumuyla ilgili iddialar yaptığı birkaç durumdan biridir.)

Ancak, başvuru geri dönme isteği, new numaralı çıplak ağa başvurmadan ve işaretçileri.

Tony& 
Movie::addTony() 
{ 
    auto tony = std::make_unique<Tony>(); 
    auto p = tony.get(); 
    attachActor(std::move(tony)); 
    return *p; 
} 

Bu kod attachActor katındaki argüman düşürmeyin varsayar. Aksi takdirde, işaretçisi attachActor'un return ed öğesinden sonra sarkar. Buna güvenilemezse, arayüzünüzü yeniden tasarlamanız ve bunun yerine paylaşılan göstericileri kullanmanız gerekir.

std::shared_ptr<Tony> 
Movie::addTony() 
{ 
    auto tony = std::make_shared<Tony>(); 
    attachActor(tony); 
    return tony; 
} 
+0

Sahiplik aktarımı, hiçbir şeyin sahibi olmadığı anlamına gelmez, yalnızca daha önce sahip olduğu nesneye artık sahip değildir. Bu tek gereksinim olsaydı, aktarım, ** uapp ile ** arasında bu nesnenin sahiplenilmesiyle gerçekleşebilirdi (ki bu, başka herhangi bir taşıtın herhangi bir tahsisatın ve tahsisatı önlemek için yaptığı şeydir). Ancak, Benjamin Lindley'nin de belirttiği gibi, std :: unique_ptr üzerinde sadece metinsel "sahipliğin aktarılması" nın ötesinde ek şartlar vardır. – Dreamer