Rumah > Artikel > pembangunan bahagian belakang > Mengapa C tidak menggunakan pengecualian bersarang untuk mengendalikan pengecualian yang dilemparkan daripada pemusnah?
Memahami Isu
Melemparkan pengecualian daripada pemusnah memperkenalkan dilema: apa yang perlu dilakukan apabila pengecualian sudah dalam penerbangan? Menimpa pengecualian sedia ada atau menyarangkan pengecualian baharu dalam pengecualian sedia ada merupakan penyelesaian yang berpotensi, tetapi telah diputuskan bahawa penamatan dengan std::terminate akan menjadi pendekatan standard.
Pertimbangan Pengecualian Bersarang
C 11 memperkenalkan ciri std::nested_exception, yang berpotensi menangani isu dengan meletakkan pengecualian lama dalam yang baharu. Walau bagaimanapun, idea ini tidak dilaksanakan.
Sebab Tidak Pelaksanaan
Satu sebab untuk tidak menggunakan pengecualian bersarang dalam konteks ini ialah hakikat bahawa std::nested_exception mempunyai penggunaan yang sangat terhad, dengan hanya satu aplikasi praktikal yang diketahui: mencipta tindanan panggilan beranotasi sepenuhnya.
Contoh ini menunjukkan cara pengecualian bersarang menyediakan cara yang mudah untuk menambah konteks dan menentukan ralat semasa penyahpepijatan:
<code class="cpp">#include <iostream> #include <sstream> #include <exception> void rethrow(const std::string& context, ...) { std::ostringstream ss; ss << context; auto sep = " : "; (void) ((ss << sep << args), sep = ", ", 0)...); try { std::rethrow_exception(std::current_exception()); } catch(const std::invalid_argument& e) { std::throw_with_nested(std::invalid_argument(ss.str())); } catch(const std::logic_error& e) { std::throw_with_nested(std::logic_error(ss.str())); } catch(...) { std::throw_with_nested(std::runtime_error(ss.str())); } } int main() { try { outer("xyz"); outer("abcd"); } catch(std::exception& e) { print_exception(e); } return 0; } void print_exception(const std::exception& e, std::size_t depth = 0) { std::cerr << "exception: " << std::string(depth, ' ') << e.what() << '\n'; try { std::rethrow_if_nested(e); } catch (const std::exception& nested) { print_exception(nested, depth + 1); } }</code>
Output Jangkaan:
exception: outer : abcd exception: inner : abcdabcd exception: really_inner exception: too long
Contoh di atas mempamerkan sarang pengecualian dan menunjukkan cara teknik ini membantu dalam mengesan ralat dan memahami susunan panggilan.
Walaupun kegunaan pengecualian bersarang dalam ini senario tertentu, keputusan untuk tidak menggunakannya dalam konteks pengecualian pemusnah berkemungkinan dibuat disebabkan oleh kemudahan dan kebolehpercayaan penamatan dengan std::terminate.
Atas ialah kandungan terperinci Mengapa C tidak menggunakan pengecualian bersarang untuk mengendalikan pengecualian yang dilemparkan daripada pemusnah?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!