2012-10-04 31 views
6

Olası Çoğalt:
How to clean initialized resources if exception thrown from constructor in c++Kuruculardaki istisnaları nasıl düzgün kullanırım?

Nasıl 6 tane oluşturulurken 6 Nesneleri oluşturma ve bu nesneler 5 nesnesi oluşturmak ve başarısız olursa kurucularınızdaki istisna işler?

Teşekkürler.

+3

Link hakkında, Als size burada verir http://stackoverflow.com/questions/12723492/how-to-clean-initialized-resources-if-exception-thrown-from-constructor-in-c? Bu üyeler üye nesneler mi? – ForEveR

+0

Hangi işleme ihtiyacınız var? Normal olarak, istisnanın yayılmasına izin verirsiniz, böylece ilk 5 nesne temiz bir şekilde yok edilir. Bazı daha fazla bağlam yararlı olabilir – jalf

+0

RAII. (Http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization) – ScaryAardvark

cevap

1

Kurucuda bir istisna atıldığında, tüm yapılandırılmış alt nesneler yok edilir. Yapılmış nesnelerin yıkıcılarına sahip olmalarının iyi bir uygulama olduğu için, bu alt nesneler için hiçbir şey yapılması gerekmemektedir. Özel durum ne zaman atılırsa, şu anda çalıştırılan yapıcının gövdesinde kalan şey temizleniyor. Bununla birlikte, bu, başka herhangi bir işlevdeki temizlikten farklı değildir.

İmha siparişinin inşaatın tersi olduğuna dikkat edin. Yani, vücuttaki temizlik ilk önce tüm alt nesiller henüz yok olduğunda başlar. Daha sonra üyeler yok edilir, daha sonra sanal olmayan temel sınıflar ve son olarak sanal temel sınıflar.

3

Her zamanki davranış, istisnanın yayılmasına izin vermektir. Tamamen inşa edilmiş temel sınıflar ve üyeler için Destructor'lar çağrılacaktır; İlk beş nesne üyelerse, doğru olarak imha edilecektir.

Bir sorunun ortaya çıkabileceği tek durum, hakkında konuştuğunuz nesnelerin dinamik olarak ayrıldığı (new kullanarak). Eğer bu durum ise: Kendinize sormanız gereken ilk şey neden? Neden nesneyi somut bir üye haline getirmiyorsunuz ve dinamik olarak ayırıyorsunuz? benim deneyimim, böyle bir ihtiyaç, çok özel bir çok özel vakalar (örneğin derleme güvenlik duvarı deyim) dışında çok nadirdir, bu durumda, normalde sınıfta tam olarak bir nesne olacaktır (örneğin uygulama nesnesi). Bu gibi durumlarda, herhangi bir sorun yoktur, çünkü bu nesnenin new başarısız olursa, geri alma gerektiren başka bir şey yapılmamıştır.

gerçekten dinamik ayırma ve kullanmak zorunda nereye derece nadir durumlarda kendinizi bulmak Eğer varsa birden fazla böyle bir nesne (örn sen polimorfik olan iki subobjects çünkü), sonra seni Her bir tahsisatın bir alt nesnenin bazı türüne sarıldığından emin olmalıyım (akıllı bir işaretçi hile yapar); İlk alt nesnesi başarıyla oluşturulduktan sonra, kurucunun daha sonraki bir noktada başarısız olması durumunda yıkıcı olarak adlandırılacaktır.

1

İstisnalarla uğraşmanın "özünde" neredeyse her şeyin yıkıcılar aracılığıyla temizlenmesi gerekir. Örneğin, bir nesneyi "yeni" yazarsanız "ham" işaretçisi alırsınız; Bir istisna bir yere atılırsa, bu ham işaretçinin düzgün bir şekilde "sil" dendiğinden emin olmalısınız, ancak başlatılmamış bir ham işaretçiyi silmediğinizden emin olun.

Bu işaretçiyi std :: unique_ptr içine kaydederseniz, hiçbir şey yapmanız gerekmez; unique_ptr yok olduğunda, nesne silinir ve nesne-imha otomatik olarak gerçekleşir: unique_ptr kapsam dışına çıktığında, derleyici temizleme, tümüyle görünmez (bu yüzden daha fazla kod temizleme ve tonlama temizleme çağrıları ile) ve otomatik olarak çağırır (böylece Artık hiç kimsenin, hiç kimsenin test etmediği nadir bir yol olduğu zaman, temizlemeyi unuttuğuna inanıyorum ”.

Aynı şey hemen hemen her kaynağa uygulanabilir; COM nesneleri için "otomatik işaretçiler" vardır (örneğin, DirectX'te kullanıldığı gibi), çoğu çerçeve muteksleri etrafına sarmak için bir "scoped lock" -type nesnesi vermelidir (böylece nesne oluşturulduğunda mutex kilitlenir ve imha edildiğinde kilidini açar) ve çeşitli Windows tutamaçlarıyla başa çıkmak için küçük paketler yazabilirsiniz.

Temel olarak, tüm temizlemenizi yıkıcılara yerleştirirseniz, sadece temizlemek için "... yakalamaya, yeniden işlemeye" gerek yoktur. Ve “daha ​​büyük” nesnelerin yıkıcıları, çoğu zaman, “içerilen” nesnelerin neredeyse tamamı kendi yıkıcıları tarafından otomatik olarak temizlendiğinden, çok basit olacaktır.