Jadi pertanyaan saya adalah ini - jika melempar dari destruktor menghasilkan perilaku yang tidak terdefinisi, bagaimana Anda menangani kesalahan yang terjadi selama destruktor?
Masalah utamanya adalah ini: Anda tidak dapat gagal untuk gagal . Apa artinya gagal gagal? Jika melakukan transaksi ke database gagal, dan gagal gagal (gagal mengembalikan), apa yang terjadi dengan integritas data kami?
Karena destruktor dipanggil untuk jalur normal dan luar biasa (gagal), mereka sendiri tidak dapat gagal atau kita "gagal gagal".
Ini adalah masalah yang sulit secara konseptual tetapi seringkali solusinya adalah dengan hanya menemukan cara untuk memastikan bahwa kegagalan tidak dapat gagal. Misalnya, database mungkin menulis perubahan sebelum melakukan ke struktur atau file data eksternal. Jika transaksi gagal, maka struktur file / data dapat dibuang. Yang harus dipastikan adalah melakukan perubahan dari struktur eksternal / mengajukan transaksi atom yang tidak dapat gagal.
Solusi pragmatis mungkin hanya memastikan bahwa kemungkinan kegagalan pada kegagalan secara astronomi tidak mungkin, karena membuat hal-hal yang mustahil untuk gagal gagal bisa menjadi hampir mustahil dalam beberapa kasus.
Solusi yang paling tepat bagi saya adalah menulis logika non-pembersihan Anda sedemikian rupa sehingga logika pembersihan tidak dapat gagal. Misalnya, jika Anda tergoda untuk membuat struktur data baru untuk membersihkan struktur data yang ada, maka mungkin Anda mungkin ingin membuat struktur tambahan di muka sehingga kami tidak lagi harus membuatnya di dalam destruktor.
Memang ini jauh lebih mudah diucapkan daripada dilakukan, diakui, tapi itu satu-satunya cara yang benar-benar tepat untuk melakukannya. Kadang-kadang saya pikir harus ada kemampuan untuk menulis logika destruktor terpisah untuk jalur eksekusi normal jauh dari yang luar biasa, karena kadang-kadang destruktor merasa sedikit seperti mereka memiliki dua kali lipat tanggung jawab dengan mencoba menangani keduanya (contohnya adalah penjaga ruang lingkup yang membutuhkan pemecatan eksplisit. ; mereka tidak akan memerlukan ini jika mereka bisa membedakan jalur kehancuran yang luar biasa dari yang tidak luar biasa).
Masalah utamanya adalah kita tidak bisa gagal untuk gagal, dan ini adalah masalah desain konseptual yang sulit untuk dipecahkan dengan sempurna dalam semua kasus. Itu menjadi lebih mudah jika Anda tidak terlalu terbungkus dalam struktur kontrol yang kompleks dengan banyak objek kecil berinteraksi satu sama lain, dan sebaliknya memodelkan desain Anda dengan cara yang sedikit lebih massal (contoh: sistem partikel dengan destruktor untuk menghancurkan seluruh partikel sistem, bukan destruktor non-sepele terpisah per partikel). Ketika Anda memodelkan desain Anda pada tingkat yang lebih kasar ini, Anda memiliki lebih sedikit destruktor non-sepele untuk ditangani, dan juga dapat sering membeli apa pun yang diperlukan memori / pemrosesan untuk memastikan bahwa destruktor Anda tidak dapat gagal.
Dan itu salah satu solusi termudah secara alami adalah dengan menggunakan destruktor lebih jarang. Dalam contoh partikel di atas, mungkin saat menghancurkan / mengeluarkan partikel, beberapa hal harus dilakukan yang bisa gagal karena alasan apa pun. Dalam hal itu, alih-alih menggunakan logika seperti itu melalui dtor partikel yang dapat dieksekusi di jalur yang luar biasa, Anda bisa melakukan semuanya dengan sistem partikel ketika menghilangkan partikel. Menghapus partikel mungkin selalu dilakukan selama jalur yang tidak biasa. Jika sistem dihancurkan, mungkin ia bisa membersihkan semua partikel dan tidak repot-repot dengan logika penghilangan partikel individu yang bisa gagal, sementara logika yang bisa gagal hanya dieksekusi selama eksekusi normal sistem partikel ketika mengeluarkan satu atau lebih partikel.
Sering ada solusi seperti itu yang muncul jika Anda menghindari berurusan dengan banyak objek kecil dengan destruktor non-sepele. Di mana Anda bisa terjerat dalam kekacauan di mana tampaknya hampir mustahil untuk menjadi pengecualian-keselamatan adalah ketika Anda terlibat dalam banyak objek kecil yang semuanya memiliki dtor non-sepele.
Ini akan banyak membantu jika nothrow / noexcept benar-benar diterjemahkan ke dalam kesalahan kompiler jika ada sesuatu yang menspesifikasikannya (termasuk fungsi virtual yang harus mewarisi spesifikasi noexcept dari kelas dasarnya) berusaha untuk memohon apa pun yang bisa melempar. Dengan cara ini kita akan dapat menangkap semua hal ini pada waktu kompilasi jika kita benar-benar menulis destruktor yang secara tidak sengaja dapat melempar.