std :: auto_ptr - std :: unique_ptr


185

Yeni standart geldiğinde (ve bazı derleyicilerde zaten mevcut olan parçalar), yeni tipin std::unique_ptryerini alması gerekiyor std::auto_ptr.

Kullanımları tam olarak örtüşüyor mu (böylece kodum üzerinde küresel bir bulma / değiştirme yapabilirim (bunu yapmam değil, ama yaptım)) veya belgeleri okumadan belirgin olmayan bazı farklılıkların farkında olmalı mıyım?

Ayrıca doğrudan bir yedek ise, neden sadece geliştirmek yerine yeni bir isim verin std::auto_ptr?

Yanıtlar:


219

Global bir bul / değiştir yapamazsınız çünkü auto_ptr(bilinen sonuçlarla) bir kopyalayabilirsiniz , ancak a unique_ptryalnızca taşınabilir. Benzeyen herhangi bir şey

std::auto_ptr<int> p(new int);
std::auto_ptr<int> p2 = p; 

en azından böyle olmak zorunda kalacak

std::unique_ptr<int> p(new int);
std::unique_ptr<int> p2 = std::move(p);

Diğer farklara gelince, unique_ptrdizileri doğru bir şekilde işleyebilir (arayacak delete[], auto_ptrarayacaksa) delete.


101
Öte yandan, bu bulma / değiştirme sadece derleme hataları ile sonuçlanır, gördüğüm kadarıyla sessizce kodu kırmayacak. Derleme hatalarını daha sonra elle düzeltirseniz, bunu yapmak güvenlidir
jalf

7
@jalf: Gerçekten, auto_ptrs ve unique_ptrs ile UB ile iyi tanımlanmış bir karşı örnek düşünemiyorum.
Cubbi

1
unique_ptr, auto_ptr: support array & belirsizliği kaldırmış gibi görünüyor
Baiyan Huang

92

std::auto_ptrve std::unique_ptrbazı yerlerde uyumsuzdur ve diğerlerinde yer değiştirmede bir düşüş vardır. Yani, hiçbir bul / değiştir yeterli değildir. Ancak, bir bul / değiştir derleme hataları ile çalıştıktan sonra garip köşe durumlarda hariç her şeyi düzeltmek gerekir. Derleme hatalarının çoğunun a std::move.

  • İşlev kapsamı değişkeni:
    % 100 uyumludur, başka bir işleve değere göre geçirmediğiniz sürece.
  • Dönüş tipi:
    % 100 uyumlu değil,% 99 uyumlu yanlış görünmüyor.
  • Değere göre fonksiyon parametresi:
    Bir uyarı ile% 100 uyumlu, unique_ptrs std::moveçağrıdan geçirilmelidir . Derleyici doğru yapmazsanız şikayet edeceği için bu basit.
  • Referans ile fonksiyon parametresi:
    % 100 uyumlu.
  • Sınıf üyesi değişkeni:
    Bu zor. std::auto_ptrs kopya semantiği kötüdür. Sınıf kopyalamaya izin vermiyorsa std::unique_ptr, yerine bir damla verilir. Ancak, sınıfa makul bir kopya semantiği vermeye çalıştıysanız, std::auto_ptrişleme kodunu değiştirmeniz gerekir . Doğru değilse derleyici şikayet edeceği için bu basit. Eğer bir bir sınıfın kopyalama izin Eğer std::auto_ptrüye olmadan , daha sonra herhangi bir özel kod size utanç ve iyi şanslar.

Özetle, std::unique_ptrkırılmamış std::auto_ptr. A kullanırken genellikle hata olan derleme zamanı davranışlarına izin vermez std::auto_ptr. Dolayısıyla std::auto_ptr, gereken özenle kullandıysanız , geçiş yapmak std::unique_ptrbasit olmalıdır. std::auto_ptr'Nin tuhaf davranışına güveniyorsanız, yine de kodunuzu yeniden düzenlemeniz gerekir.


8
+1 için "yine de kodunuzu yeniden düzenlemeniz gerekiyor". auto_ptrs yalnızca 20.4.5 / 3'ün iyi olduğunu söyledikleri için iyidir.
Cubbi

8
Buna, kodunuzda auto_ptr yerine unique_ptr yazmanız ve derleme hatalarını düzeltmeniz gerektiğini ekleyeyim. Bunun kaç hata ortaya çıkaracağına şaşıracaksınız.
Bartosz Milewski

36

AFAIK, unique_ptrdoğrudan bir yedek değildir. Düzelttiği en büyük kusur, mülkiyetin örtük olarak aktarılmasıdır.

std::auto_ptr<int> a(new int(10)), b;
b = a; //implicitly transfers ownership

std::unique_ptr<int> a(new int(10)), b;
b = std::move(a); //ownership must be transferred explicitly

Öte yandan, unique_ptrtamamen yeni yeteneklere sahip olacaklar: kaplarda saklanabilirler.


8
Scott Meyers ayrıca "Effective C ++" (3. Baskı) Eşya 13'te (sayfa 64) STL kaplarının içeriklerinin "normal" kopyalama davranışı göstermesini gerektirdiğinden bahsetti, bu yüzden kaplara auto_ptrizin verilmiyor.
Qiang Xu

31

Herb Sutter'ın GotW # 89 hakkında güzel bir açıklaması var :

Auto_ptr ile olan anlaşma nedir? auto_ptr, en hayırsever olarak, C ++ hareket semantiğine sahip olmadan önce unique_ptr oluşturmak için yiğit bir girişim olarak nitelendirilir. auto_ptr artık kullanımdan kaldırılmıştır ve yeni kodda kullanılmamalıdır.

Varolan bir kod tabanında auto_ptr varsa, bir şansınız olduğunda auto_ptr yerine global_ptr yerine unique_ptr yazın; kullanımların büyük çoğunluğu aynı şekilde çalışır ve sahip olduğunuzu bilmediğiniz bir veya iki hatayı açığa çıkarabilir (derleme zamanı hatası olarak) veya düzeltebilir (sessizce).

Başka bir deyişle, global bir arama ve değiştirme kodu kodunuzu geçici olarak "bozabilir", ancak yine de yapmanız gerekir: Derleme hatalarını düzeltmek biraz zaman alabilir, ancak uzun vadede size çok daha fazla sorun kazandıracaktır.


Harika bağlantı. Çok teşekkürler!
fotNelton
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.