C ++ 11 unique_ptr ve shared_ptr birbirlerinin türüne dönüşebilir mi?


108

Mu C ++ 11 standart kütüphane bir dönüştürmek için herhangi bir fayda temin std::shared_ptretmek std::unique_ptr, ya da tam tersi? Bu güvenli işlem mi?


Lütfen "güvenli çalışmayı" tanımlayın. Ne tür bir güvenlik arıyorsunuz? ömür boyu yönetim güvenliği? İplik güvenliği?
— pürüzlüSpire

2
"STL", standart kitaplık anlamına gelmez. STL'nin hiçbir ilgisi yok shared_ptr.
— Meraklıguy

1
@jaggedSpire İplik güvenliği, sahiplerin farklı iş parçacıklarında kullandığı anlamına gelir, yani kullanım sayısı 1 değildir.
— wonderguy

@curiousguy bunu biliyordum. Demek istediğim, OP'nin sorusunda "güvenlik" iyi tanımlanmamıştı ve birden fazla tür olduğu için ne tür "güvenlik" i kastettiğini netleştirmesi gerekiyordu.
— jaggedSpire

Yanıtlar:


174

std::unique_ptrözel mülkiyeti ifade etmenin C ++ 11 yoludur, ancak en çekici özelliklerinden biri, kolayca ve verimli bir şekilde std::shared_ptr.

Bu, std::unique_ptrfabrika işlevi dönüş türü olarak neden bu kadar uygun olduğunun önemli bir parçasıdır . Fabrika işlevleri, arayanların geri döndükleri nesne için özel sahiplik semantiğini kullanmak isteyip istemediklerini veya paylaşılan sahipliğin (yani std::shared_ptr) daha uygun olup olmayacağını bilemez . std::unique_ptrFabrikalar, bir geri göndererek arayanlara en verimli akıllı işaretçiyi sağlar, ancak arayanların onu daha esnek kardeşiyle değiştirmesini engellemezler.

std::shared_ptriçin std::unique_ptrizin verilmez. Bir kaynağın yaşam boyu yönetimini bir kaynağa std::shared_ptrdönüştürdüğünüzde, fikrinizi değiştirmezsiniz. Referans sayısı bir olsa bile, örneğin bir yönetime sahip olmak için kaynağın sahipliğini geri alamazsınız std::unique_ptr.

Referans: Etkili Modern C ++. 42 C ++ 11 VE C ++ 14 KULLANIMINIZI GELİŞTİRMENİN ÖZEL YOLLARI. Scott Meyers.

Kısacası, kolayca ve verimli bir şekilde dönüştürebilir std::unique_ptriçin std::shared_ptrancak dönüştürmek olamaz std::shared_ptriçin std::unique_ptr.

Örneğin:

std::unique_ptr<std::string> unique = std::make_unique<std::string>("test");
std::shared_ptr<std::string> shared = std::move(unique);

veya:

std::shared_ptr<std::string> shared = std::make_unique<std::string>("test");

10
...Bunu nasıl yapıyorsun?
— Jake

4
@Jake Bir örnek ekledim
— chema989

İzin verilmez iken derleyici (en azından değil gcc) aslında farkında olun değil yanlışlıkla (örneğin üye değişkenin işaretçi türünü değiştirerek) bir atarsanız önlemek (veya hatta uyar) std::unique_ptra std::shared_ptr.
— StefanQ


@StefanQ Bir std::unique_ptriçine a atamasına izin verilmediğini düşündüren nedir std::shared_ptr? Standart kütüphane bir hareket atama operatörü tanımlar template<class Y, class Deleter> shared_ptr& operator=(std::unique_ptr<Y, Deleter>&& r); için std::shared_ptr<T>.
— cuddlebugCuller

-8

Unique_ptr u_ptr verildiğinde, shared_ptr s_ptr oluşturun:

std::shared_ptr<whatever> s_ptr(u_ptr.release());

Diğer tarafa gitmek pratik değildir.


30
İşte "doğru" yol:std::shared_ptr<whatever> s_ptr(std::move(u_ptr));
— emlai

7
Ve işte std::shared_ptr<whatever> s_ptr{std::move(u_ptr)};
— bilgiççe

3
Bununla ilgili daha az güvenli olan ne?
— nmr

7
@VioletGiraffe • Sanırım polyvertex, sessiz daraltma dönüşümlerini önleyen ve tek tip bir sözdizimiyle üye başlatmayı barındıran yeni başlatma listesi sözdizimini kullanmayı iyi bir alışkanlık olarak savunuyor. Birinden altı, diğerinden yarım düzine mi?
— Eljay

10
@nmr Güvensiz çünkü Deleteriçinde depolananları kaybedebilirsinizunique_ptr
— Zang MingJie
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.