Benim sorum şu - eğer bir yıkıcıdan atmak tanımsız davranışla sonuçlanırsa, bir yıkıcı sırasında meydana gelen hataları nasıl ele alırsınız?
Ana sorun şudur: Başarısız olamaz . Ne de olsa başarısız olmak ne demektir? Veritabanına işlem yapmak başarısız olursa ve başarısız olursa (geri alınamazsa), verilerimizin bütünlüğüne ne olur?
Yıkıcılar hem normal hem de istisnai (başarısız) yollar için çağrıldıklarından, kendileri başarısız olamazlar ya da "başarısız başarısız oluruz".
Bu kavramsal olarak zor bir sorundur, ancak çoğu zaman çözüm, başarısızlığın başarısız olamayacağından emin olmak için bir yol bulmaktır. Örneğin, bir veritabanı bir dış veri yapısına veya dosyasına bağlanmadan önce değişiklikler yazabilir. İşlem başarısız olursa, dosya / veri yapısı atılabilir. Bundan sonra tek yapması gereken, o dış yapıdan / dosyadan değişiklikleri yerine getiremeyen bir atomik işlemin gerçekleştirilmemesidir.
Pragmatik çözüm belki de başarısızlık konusunda başarısız olma şansının astronomik olarak imkansız olduğundan emin olmaktır, çünkü bazı durumlarda başarısızlık yapmayı imkansız hale getirmek neredeyse imkansız olabilir.
Benim için en uygun çözüm, temizleme olmayan mantığınızı, temizleme mantığı başarısız olmayacak şekilde yazmaktır. Örneğin, mevcut bir veri yapısını temizlemek için yeni bir veri yapısı oluşturmak istiyorsanız, belki de bu yardımcı yapıyı önceden bir yıkıcı içinde yaratmamız gerekmeyecek şekilde yaratmayı deneyebilirsiniz.
Bu, söylenenden çok daha kolay, ama bunu yapmak için gördüğüm tek gerçekten doğru yol. Bazen normal yürütme yolları için istisnai yollardan ayrı bir yıkıcı mantık yazma yeteneği olması gerektiğini düşünüyorum, çünkü bazen yıkıcılar her ikisini de ele almaya çalışarak sorumlulukları iki katına çıkarmış gibi hissediyorlar (bir örnek açık işten çıkarma gerektiren kapsam korumaları ; eğer istisnai imha yollarını istisnai olmayan yollardan ayırabilirlerse buna ihtiyaç duymazlar).
Yine de nihai sorun, başarısız olamayız ve her durumda mükemmel bir şekilde çözülmesi zor bir kavramsal tasarım problemidir. Birbiri ile etkileşen tonlarca ufacık nesne ile karmaşık kontrol yapılarına çok fazla sarılmazsanız ve tasarımlarınızı biraz daha hantal bir şekilde modellerseniz (örnek: tüm parçacığı yok etmek için bir yıkıcı ile parçacık sistemi) daha kolaylaşır sistem, parçacık başına ayrı bir önemsiz yıkıcı değil). Tasarımlarınızı bu tür daha kaba düzeyde modellediğinizde, uğraşmak için önemsiz daha az yıkıcıya sahip olursunuz ve ayrıca yıkıcılarınızın başarısız olamayacağından emin olmak için gereken bellek / işleme yükünü de ödeyebilirsiniz.
Doğal olarak en kolay çözümlerden biri de yıkıcıları daha az kullanmaktır. Yukarıdaki parçacık örneğinde, belki de bir parçacığı yok ettikten / çıkardıktan sonra, hangi nedenle olursa olsun başarısız olabilecek bazı şeyler yapılmalıdır. Bu durumda, bu tür bir mantığı, istisnai bir yolda yürütülebilen parçacığın dtor'undan çağırmak yerine, parçacığı kaldırdığında parçacık sistemi tarafından her şeyin yapılmasını sağlayabilirsiniz . Bir parçacığın çıkarılması her zaman istisnai olmayan bir yol sırasında yapılabilir. Sistem yok edilirse, belki sadece tüm parçacıkları temizleyebilir ve başarısız olabilecek tek tek parçacık çıkarma mantığı ile uğraşmazken, başarısız olabilecek mantık sadece bir veya daha fazla parçacığı giderirken parçacık sisteminin normal yürütülmesi sırasında yürütülür.
Önemsiz yıkıcılara sahip çok sayıda ufacık nesne ile uğraşmaktan kaçınırsanız, bunun gibi çözümler genellikle vardır. İstisna güvenliği olmanın neredeyse imkansız olduğu bir karmaşaya karışabileceğiniz yer, hepsi önemsiz olmayan dtorlara sahip birçok ufacık nesneye karıştığınız zamandır.
Nothrow / noexcept, onu belirten herhangi bir şey (temel sınıfının noexcept spesifikasyonunu devralması gereken sanal işlevler dahil) atabilecek herhangi bir şeyi çağırmaya çalıştıysa, aslında bir derleyici hatasına dönüştürülürse çok yardımcı olacaktır. Eğer istemeden bir fırlatıcı yazabilirsek, bu şekilde tüm bunları derleme zamanında yakalayabiliriz.