2011-07-09 16 views
12

boost::/std::shared_ptr, kendi deleterlerini silme avantajına sahip olduğundan,Eğer her zaman bir share_ptr içinde saklarsanız, Arayüzünüz için gerekli sanal bir yıkıcı mıdır?

#include <memory> 

typedef std::shared_ptr<void> gc_ptr; 

int main(){ 
    gc_ptr p1 = new int(42); 
    gc_ptr p2 = new float(3.14159); 
    gc_ptr p3 = new char('o'); 
} 

gibi güzel şeyler yapabilirsiniz. Ve bu, kaydedilmekte olan doğru delet sayesinde tüm işaretçileri doğru şekilde silecektir.

Arayüzünüzün her uygulamasının her zaman shared_ptr<Interface> (veya make_shared<Interface>) ile oluşturulmasını sağlarsanız, aslında bir virtual destructor'ına ihtiyacınız var mı? Xzx22'yi yine de beyan ederim, ama sadece bilmek istiyorum, çünkü shared_ptr her zaman başlatılan türü silecektir (başka bir özel deleter verilmedikçe).

+1

olası bir kopyası [shared_ptr magic:)] (http://stackoverflow.com/questions/3899790/shared-ptr-magic) –

+0

@Armen: Bu bir kopya değil, nasıl 'shared_ptr' komutunu sormuyor; bu, ama sanal bir yıkıcı kullanmanız gerekip gerekmediğini * * bilmek '' shared_ptr' bu sihiri yapar. –

+1

@David: Hayır, yapmıyor. Zaten bir sanal yıkıcı kullanacağını söylüyor. Birine sahip olmamanın sorun olup olmadığını soruyor. Yani bu bir kopya –

cevap

12

Hala elde edilecek içindir sınıflar için ortak kuralı takip ediyorum tüm kullanımları denetleyemez ve bu basit kural, hiyerarşideki yanlış düzeyden delete'u denerseniz, derleyicinin işaretleneceği anlamına gelir. base olmayan bir kamu sanal yıkıcı ve foo döner sahiptir

base* foo(); 
shared_ptr<base> p(foo()); 

ise: o argüman olarak kullanılmıştır statik tipte yıkıcı arayacak Sadece bu değil, uygun yıkıcı arayacak garanti etmez shared_ptr düşünün base, sonra shared_ptr türeten bir tür doğru yıkıcıyı çağırmak için başarısız olur. base destructor sanal ise, her şey iyi olacak, eğer korunursa, derleyici size orada bir hata olduğunu söyleyecektir.

+0

"Her halükarda sanal olarak ilan ediyorum, [...]". :) Tüm örnekleme noktalarını kontrol edememe konusunda iyi bir nokta. Yine de, her zaman adlandırılmış bir kurucu ile yapabilirsin, ama bu muhtemelen çok hoş görünmüyor. – Xeo

+1

Uyarı: Korumalı yıkıcılar, şu anda bir istisna atmasalar bile, “is_nothrow_destructible :: value” için doğru yanıt vermiyor. Bunun için genel seçeneği tercih ederim. –

+0

@Howard: 'is_nothrow_destructible' hakkında bilgi için teşekkürler. Doğru olanı yapmak gibi görünüyor. Neden şu anda, yıkıcı olmayan bir şey için "yıkılmaz" olduğunu doğru bir şekilde rapor etmesine neden izin verdiniz? –

İlgili konular