рд╡рд┐рдирд╛рд╢рдХрд╛рд░реА рдЕрдкрд╡рд╛рдж

рдПрдХ рдмрд╛рд░ рдлрд┐рд░ рдХреНрдпреЛрдВ рд╡рд┐рдирд╛рд╢рдХрд╛рд░реА рдореЗрдВ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдлреЗрдВрдХрдирд╛ рдмреБрд░рд╛ рд╣реИ


рдХрдИ рд╕реА ++ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рд░реНрдм рд╕рдЯрд░ ) рд╣рдореЗрдВ рд╕рд┐рдЦрд╛рддреЗ рд╣реИрдВ рдХрд┐ рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдореЗрдВ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрдирд╛ рдмреБрд░рд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдлреЗрдВрдХреЗ рдЧрдП рдПрдХ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде рд╕реНрдЯреИрдХ рдкреНрд░рдореЛрд╢рди рдХреЗ рджреМрд░рд╛рди рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдореЗрдВ рдорд┐рд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрджрд┐ рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рдПрдХ рдФрд░ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ std рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛ :: рд╕рдорд╛рдкреНрдд () ред рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ C ++ 17 рднрд╛рд╖рд╛ рдорд╛рдирдХ (рдЗрд╕рдХреЗ рдмрд╛рдж рдореИрдВ рдбреНрд░рд╛рдлреНрдЯ N4713 рдХреЗ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рдЙрдкрд▓рдмреНрдз рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рддрд╛ рд╣реВрдВ ) рд╣рдореЗрдВ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдмрддрд╛рддрд╛ рд╣реИ:


18.5.1 std :: рд╕рдорд╛рдкреНрддрд┐ () рдлрд╝рдВрдХреНрд╢рди [рдХреЛ рдЫреЛрдбрд╝рдХрд░

1 рдХреБрдЫ рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдХрдо рд╕реВрдХреНрд╖реНрдо рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рддрдХрдиреАрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдХреЛ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред [рдзреНрдпрд╛рди рджреЗрдВ:

рдпреЗ рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рд╣реИрдВ:

...

(1.4) рдЬрдм рд╕реНрдЯреИрдХ рдЕрдирдЗрдВрдбрд┐рдВрдЧ (18.2) рдХреЗ рджреМрд░рд╛рди рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХрд╛ рд╡рд┐рдирд╛рд╢ рдПрдХ рдЕрдкрд╡рд╛рдж рдХреЛ рдлреЗрдВрдХрдХрд░ рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рдпрд╛

...

- рдЕрдВрддрд┐рдо рдиреЛрдЯ]

рдЖрдЗрдП рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдкрд░ рдЬрд╛рдБрдЪ рдХрд░реЗрдВ:


#include <iostream> class PrintInDestructor { public: ~PrintInDestructor() noexcept { std::cerr << "~PrintInDestructor() invoked\n"; } }; void throw_int_func() { std::cerr << "throw_int_func() invoked\n"; throw 1; } class ThrowInDestructor { public: ~ThrowInDestructor() noexcept(false) { std::cerr << "~ThrowInDestructor() invoked\n"; throw_int_func(); } private: PrintInDestructor member_; }; int main(int, char**) { try { ThrowInDestructor bad; throw "BANG!"; } catch (int i) { std::cerr << "Catched int exception: " << i << "\n"; } catch (const char* c) { std::cerr << "Catched const char* exception: " << c << "\n"; } catch (...) { std::cerr << "Catched unknown exception\n"; } return 0; } 

рдкрд░рд┐рдгрд╛рдо:


 ~ThrowInDestructor() invoked throw_int_func() invoked ~PrintInDestructor() invoked terminate called after throwing an instance of 'int' Aborted 

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ PrintInDestructor рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдХреЛ рдЕрднреА рднреА рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рджреВрд╕рд░рд╛ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрдиреЗ рдХреЗ рдмрд╛рдж, рд╕реНрдЯреИрдХ рдкрджреЛрдиреНрдирддрд┐ рдмрд╛рдзрд┐рдд рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдорд╛рдирдХ (рд╡рд╣реА рдкреИрд░рд╛рдЧреНрд░рд╛рдл 18.5.1) рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╣рддрд╛ рд╣реИ:


2 ... рдРрд╕реА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЬрд╣рд╛рдВ рдХреЛрдИ рднреА рдореИрдЪрд┐рдВрдЧ рд╣реИрдВрдбрд▓рд░ рдирд╣реАрдВ рдорд┐рд▓рддрд╛ рд╣реИ,
рдпрд╣ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд-рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╕реНрдЯреИрдХ :: рд╕рдорд╛рдкреНрддрд┐ () рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╕реНрдЯреИрдХ рдирд┐рд░рд╛рдзрд╛рд░ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдореЗрдВ
рд╡рд╣ рд╕реНрдерд┐рддрд┐ рдЬрд╣рд╛рдВ рд╣реИрдВрдбрд▓рд░ (18.3) рдХреА рдЦреЛрдЬ рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рдмрд╕реЗ рдмрд╛рд╣рд░реА рдмреНрд▓реЙрдХ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рддреА рд╣реИ a
рдЧреИрд░-рдлреЗрдВрдХ рдЕрдкрд╡рд╛рдж рд╡рд┐рдирд┐рд░реНрджреЗрд╢ (18.4), рдпрд╣ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди-рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╕реНрдЯреИрдХ рдирд┐рд░рд╛рдзрд╛рд░ рд╣реИ,
рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдкреВрд░реНрд╡рд╡рдд рдХрд░реЗрдВ, рдпрд╛ std :: terminate () ...

рдореИрдВрдиреЗ рдЬреАрд╕реАрд╕реА (8.2, 7.3) рдФрд░ рдХреНрд▓реИрдВрдЧ (6.0, 5.0) рдХреЗ рдХрдИ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛, рд╣рд░ рдЬрдЧрд╣ рд╕реНрдЯреИрдХ рдХрд╛ рдкреНрд░рдЪрд╛рд░ рдЬрд╛рд░реА рд╣реИред рдпрджрд┐ рдЖрдк рдПрдХ рд╕рдВрдХрд▓рдХ рдкрд░ рдЖрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди-рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЕрд▓рдЧ рд╣реИ, рддреЛ рдХреГрдкрдпрд╛ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦреЗрдВред


рдпрд╣ рднреА рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рд╕реНрдЯреИрдб: рдЯрд░реНрдорд┐рдиреЗрдЯ () рдХреЛ рддрдм рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рд╕реНрдЯреИрдХ рдХреЗрд╡рд▓ рдЕрдирд╡рд╛рдЙрдВрдб рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдПрдХ рдЕрдкрд╡рд╛рдж рд╡рд┐рдзреНрд╡рдВрд╕рдХ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд╛рд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдХреЗ рдЕрдВрджрд░ рдПрдХ рдХреЛрд╢рд┐рд╢ / рдХреИрдЪ рдмреНрд▓реЙрдХ рд╣реИ рдЬреЛ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝рддрд╛ рд╣реИ рдФрд░ рдЖрдЧреЗ рдирд╣реАрдВ рдлреЗрдВрдХрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдмрд╛рд╣рд░реА рдЕрдкрд╡рд╛рдж рдХреЗ рдвреЗрд░ рдХреЗ рдкреНрд░рдЪрд╛рд░ рдХреЛ рдмрд╛рдзрд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред


 class ThrowCatchInDestructor { public: ~ThrowCatchInDestructor() noexcept(false) { try { throw_int_func(); } catch (int i) { std::cerr << "Catched int in ~ThrowCatchInDestructor(): " << i << "\n"; } } private: PrintInDestructor member_; }; int main(int, char**) { try { ThrowCatchInDestructor good; std::cerr << "ThrowCatchInDestructor instance created\n"; throw "BANG!"; } catch (int i) { std::cerr << "Catched int exception: " << i << "\n"; } catch (const char* s) { std::cerr << "Catched const char* exception: " << s << "\n"; } catch (...) { std::cerr << "Catched unknown exception\n"; } return 0; } 

рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ


 ThrowCatchInDestructor instance created throw_int_func() invoked Catched int in ~ThrowCatchInDestructor(): 1 ~PrintInDestructor() invoked Catched const char* exception: BANG! 

рдЕрдкреНрд░рд┐рдп рд╕реНрдерд┐рддрд┐рдпреЛрдВ рд╕реЗ рдХреИрд╕реЗ рдмрдЪреЗрдВ? рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ: рдХрднреА рднреА рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдореЗрдВ рдЕрдкрд╡рд╛рдж рди рдлреЗрдВрдХреЗрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдпрд╣ рд╕рд░рд▓ рдФрд░ рд╕реБрдВрджрд░ рдврдВрдЧ рд╕реЗ рдЗрд╕ рд╕рд░рд▓ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рдорд╣рд╕реВрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрддрдирд╛ рд╕рд░рд▓ рдирд╣реАрдВ рд╣реИред


рдпрджрд┐ рдЖрдк рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ ...


рдореИрдВ рддреБрд░рдВрдд рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдореИрдВ рд╡рд┐рдзреНрд╡рдВрд╕рдХ рд╕реЗ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдлреЗрдВрдХрдиреЗ рдХрд╛ рдФрдЪрд┐рддреНрдп рд╕рд╛рдмрд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдФрд░ рд╕рдЯрд░, рдореЗрдпрд░реНрд╕ рдФрд░ рдЕрдиреНрдп C ++ рдЧреБрд░реБрдУрдВ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░рддреЗ рд╣реБрдП, рдореИрдВ рдЖрдкрд╕реЗ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдРрд╕рд╛ рдХрднреА рди рдХрд░реЗрдВ (рдХрдо рд╕реЗ рдХрдо рдирдП рдХреЛрдб рдореЗрдВ)ред рдлрд┐рд░ рднреА, рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЕрднреНрдпрд╛рд╕ рдореЗрдВ, рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдХреЛрдб рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдЙрдЪреНрдЪ рдорд╛рдирдХреЛрдВ рдХрд╛ рдиреЗрддреГрддреНрд╡ рдХрд░рдирд╛ рдЗрддрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдХреНрд╕рд░ рдиреАрдЪреЗ рд╡рд░реНрдгрд┐рдд рддрдХрдиреАрдХ рдбреАрдмрдЧрд┐рдВрдЧ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреА рд╣реИред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рд░реИрдкрд░ рдХреНрд▓рд╛рд╕ рдХреЗ рд╕рд╛рде рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╡рд┐рдХрд╕рд┐рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬреЛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрд╕рд╛рдзрди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рдПрдирдХреИрдкреНрд╕реБрд▓реЗрдЯ рдХрд░рддрд╛ рд╣реИред RAII рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рд╣рдо рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рд╕рдВрд╕рд╛рдзрди рдХреЛ рдкрдХрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдореЗрдВ рдореБрдХреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╕рдВрд╕рд╛рдзрди рдореБрдХреНрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рдП рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛? рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд▓реНрдк:


  • рддреНрд░реБрдЯрд┐ рдХреЛ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдХрд░реЗрдВред рдмреБрд░рд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдПрдХ рдРрд╕реА рд╕рдорд╕реНрдпрд╛ рдХреЛ рдЫрд┐рдкрд╛ рд░рд╣реЗ рд╣реИрдВ рдЬреЛ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдЕрдиреНрдп рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░ рд╕рдХрддреА рд╣реИред
  • рд▓реЙрдЧ рдореЗрдВ рд▓рд┐рдЦреЗрдВред рд╕рд┐рд░реНрдл рдЗрд╕реЗ рдирдЬрд░рдЕрдВрджрд╛рдЬ рдХрд░рдиреЗ рд╕реЗ рдмреЗрд╣рддрд░ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдмреБрд░рд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдЕрдкрдирд╛рдИ рдЧрдИ рд▓реЙрдЧрд┐рдВрдЧ рдиреАрддрд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдЬрд╛рдирддреА рд╣реИ рдЬреЛ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИред рдорд╛рдирдХ рд▓реЙрдЧ рдХреЛ / dev / null рдкрд░ рдкреБрдирд░реНрдирд┐рд░реНрджреЗрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдлрд┐рд░ рд╕реЗ, рд╣рдо рдПрдХ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рджреЗрдЦреЗрдВрдЧреЗред
  • рд╕рдВрд╕рд╛рдзрди рдХреЛ рдПрдХ рдЕрд▓рдЧ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд▓реЗ рдЬрд╛рдПрдВ рдЬреЛ рдПрдХ рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдпрд╛ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИ, рдФрд░ рд╡рд░реНрдЧ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЕрдкрдиреЗ рджрдо рдкрд░ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдмреБрд░рд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдРрд╕рд╛ рдХрд░рдирд╛ рднреВрд▓ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╣рдореЗрдВ рдПрдХ рд╕рдВрд╕рд╛рдзрди рд░рд┐рд╕рд╛рд╡ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧрд╛ред
  • рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджреЗрдВред рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЕрдЪреНрдЫрд╛ рд╣реИ, рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд░реНрдЧ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдкрд╡рд╛рдж рдХреЛ рдкрдХрдбрд╝ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдорд╛рдирдХ рддрд░реАрдХреЗ рд╕реЗ рддреНрд░реБрдЯрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред рд╕реНрдЯреИрдХ рдкреНрд░рдореЛрд╢рди рдХреЗ рджреМрд░рд╛рди рдЦрд░рд╛рдм, рдЬреИрд╕рд╛ рдХрд┐ std рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИ :: рд╕рдорд╛рдкреНрддрд┐ () ред

рдпрд╣ рдХреИрд╕реЗ рд╕рдордЭрд╛ рдЬрд╛рдП рдХрд┐ рд╣рдо рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╕реНрдЯреИрдХ рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╣реИрдВ рдпрд╛ рдирд╣реАрдВ? C ++ рдореЗрдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖ рдлрд╝рдВрдХреНрд╢рди std :: unc-0_exception () рд╣реИ ред рдЗрд╕рдХреА рдорджрдж рд╕реЗ, рд╣рдо рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдХреБрдЫ рдХрдо рд╕рд╣реА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕реНрдЯреИрдХ рдкреНрд░рдореЛрд╢рди рдХреЗ рджреМрд░рд╛рди рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЧреНрд░рдгреА рдирд╣реАрдВ рд╣реИред


 class ThrowInDestructor { public: ~ThrowInDestructor() noexcept(false) { if (std::uncaught_exception()) { std::cerr << "~ThrowInDestructor() stack unwinding, not throwing\n"; } else { std::cerr << "~ThrowInDestructor() normal case, throwing\n"; throw_int_func(); } } private: PrintInDestructor member_; }; int main(int, char**) { try { ThrowInDestructor normal; std::cerr << "ThrowInDestructor normal destruction\n"; } catch (int i) { std::cerr << "Catched int exception: " << i << "\n"; } try { ThrowInDestructor stack_unwind; std::cerr << "ThrowInDestructor stack unwinding\n"; throw "BANG!"; } catch (int i) { std::cerr << "Catched int exception: " << i << "\n"; } catch (const char* s) { std::cerr << "Catched const char* exception: " << s << "\n"; } catch (...) { std::cerr << "Catched unknown exception\n"; } return 0; } 

рдкрд░рд┐рдгрд╛рдо:


 ThrowInDestructor normal destruction ~ThrowInDestructor() normal case, throwing throw_int_func() invoked ~PrintInDestructor() invoked Catched int exception: 1 ThrowInDestructor stack unwinding ~ThrowInDestructor() stack unwinding, not throwing ~PrintInDestructor() invoked Catched const char* exception: BANG! 

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ std :: uncaught_exception () рдлрд╝рдВрдХреНрд╢рди C ++ рдорд╛рдирдХ 17 рдХреЗ рдмрд╛рдж рд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдЙрджрд╛рд╣рд░рдг рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рдВрдмрдВрдзрд┐рдд vorning рдХреЛ рджрдмрд╛рдпрд╛ рдЬрд╛рдирд╛ рд╣реИ ( рд▓реЗрдЦ рд╕реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рднрдВрдбрд╛рд░ рджреЗрдЦреЗрдВ )ред


рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдЬрд╛рдВрдЪрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣рдо рд╕реНрдЯреИрдХ рдХреЛ рдХрддрд╛рдИ рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╣реИрдВ рдпрд╛ рдирд╣реАрдВред рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдордЭрдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╕реНрдЯреИрдХ рдкреНрд░рдореЛрд╢рди рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рджреМрд░рд╛рди рд╡рд░реНрддрдорд╛рди рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдирддреАрдЬрддрди, рдЕрдЧрд░ рдХреЛрдИ рд╕реНрдЯреИрдХ рдкреНрд░рдореЛрд╢рди рд╣реИ, рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреЗ рд╡рд┐рдирд╛рд╢рдХрд░реНрддрд╛ рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ std :: unc-0_exception () рдЕрднреА рднреА рд╕рд╣реА рд▓реМрдЯреЗрдЧрд╛ред


 class MayThrowInDestructor { public: ~MayThrowInDestructor() noexcept(false) { if (std::uncaught_exception()) { std::cerr << "~MayThrowInDestructor() stack unwinding, not throwing\n"; } else { std::cerr << "~MayThrowInDestructor() normal case, throwing\n"; throw_int_func(); } } }; class ThrowCatchInDestructor { public: ~ThrowCatchInDestructor() noexcept(false) { try { MayThrowInDestructor may_throw; } catch (int i) { std::cerr << "Catched int in ~ThrowCatchInDestructor(): " << i << "\n"; } } private: PrintInDestructor member_; }; int main(int, char**) { try { ThrowCatchInDestructor stack_unwind; std::cerr << "ThrowInDestructor stack unwinding\n"; throw "BANG!"; } catch (int i) { std::cerr << "Catched int exception: " << i << "\n"; } catch (const char* s) { std::cerr << "Catched const char* exception: " << s << "\n"; } catch (...) { std::cerr << "Catched unknown exception\n"; } return 0; } 

рдкрд░рд┐рдгрд╛рдо:


 ThrowInDestructor stack unwinding ~MayThrowInDestructor() stack unwinding, not throwing ~PrintInDestructor() invoked Catched const char* exception: BANG! 

рдирдП C ++ 17 рдорд╛рдирдХ рдореЗрдВ, std :: unc-0_exception () рдлрд╝рдВрдХреНрд╢рди рдХреЛ std рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкреЗрд╢ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ : uncaught_exception () (рдмрд╣реБрд╡рдЪрди рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ), рдЬреЛ рдмреВрд▓рд┐рдпрди рдорд╛рди рдХреЗ рдмрдЬрд╛рдп рд╡рд░реНрддрдорд╛рди рдореЗрдВ рд╕рдХреНрд░рд┐рдп рдЕрдкрд╡рд╛рджреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рджреЗрддрд╛ рд╣реИ (рдпрд╣рд╛рдВ рдПрдХ рд╡рд┐рд╕реНрддреГрдд рдФрдЪрд┐рддреНрдп рд╣реИ )ред


рдпрд╣ рдХреИрд╕реЗ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рд╕рдорд╕реНрдпрд╛ рдХреЛ std :: uncaught_exception () рдХреЗ рд╕рд╛рде рд╣рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:


 class MayThrowInDestructor { public: MayThrowInDestructor() : exceptions_(std::uncaught_exceptions()) {} ~MayThrowInDestructor() noexcept(false) { if (std::uncaught_exceptions() > exceptions_) { std::cerr << "~MayThrowInDestructor() stack unwinding, not throwing\n"; } else { std::cerr << "~MayThrowInDestructor() normal case, throwing\n"; throw_int_func(); } } private: int exceptions_; }; class ThrowCatchInDestructor { public: ~ThrowCatchInDestructor() noexcept(false) { try { MayThrowInDestructor may_throw; } catch (int i) { std::cerr << "Catched int in ~ThrowCatchInDestructor(): " << i << "\n"; } } private: PrintInDestructor member_; }; int main(int, char**) { try { ThrowCatchInDestructor stack_unwind; std::cerr << "ThrowInDestructor stack unwinding\n"; throw "BANG!"; } catch (int i) { std::cerr << "Catched int exception: " << i << "\n"; } catch (const char* s) { std::cerr << "Catched const char* exception: " << s << "\n"; } catch (...) { std::cerr << "Catched unknown exception\n"; } return 0; } 

рдкрд░рд┐рдгрд╛рдо:


 ThrowInDestructor stack unwinding ~MayThrowInDestructor() normal case, throwing throw_int_func() invoked Catched int in ~ThrowCatchInDestructor(): 1 ~PrintInDestructor() invoked Catched const char* exception: BANG! 

рдЬрдм рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдмрд╛рд░ рдореЗрдВ рдХреБрдЫ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдлреЗрдВрдХрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ


std :: uncaught_exception () рдХреЙрд▓рд┐рдВрдЧ рд╕реЗ рдмрдЪрд╛ рдЬрд╛рддрд╛ рд╣реИ std :: рд╕рдорд╛рдкреНрдд () , рд▓реЗрдХрд┐рди рдХрдИ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рдВрднрд╛рд▓рдиреЗ рдореЗрдВ рдорджрдж рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ, рдореИрдВ рдПрдХ рдРрд╕рд╛ рддрдВрддреНрд░ рд░рдЦрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдЬреЛ рдореБрдЭреЗ рд╕рднреА рдлреЗрдВрдХреЗ рдЧрдП рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛, рдФрд░ рдлрд┐рд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рд╕реНрдерд╛рди рдкрд░ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░реЗрдЧрд╛ред


рдореИрдВ рдПрдХ рдмрд╛рд░ рдлрд┐рд░ рдпрд╛рдж рджрд┐рд▓рд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдореЗрд░реЗ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рддрдВрддреНрд░ рдХреЗрд╡рд▓ рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдФрджреНрдпреЛрдЧрд┐рдХ рдХреЛрдб рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд╢рдВрд╕рд┐рдд рдирд╣реАрдВ рд╣реИред

рд╡рд┐рдЪрд╛рд░ рдХрд╛ рд╕рд╛рд░ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдкрдХрдбрд╝рдирд╛ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдХрдВрдЯреЗрдирд░ рдореЗрдВ рд╕рд╣реЗрдЬрдирд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдЙрдиреНрд╣реЗрдВ рдПрдХ рдмрд╛рд░ рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдФрд░ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╣реИред рдЕрдкрд╡рд╛рдж рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЛ рд╕рд╣реЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, C ++ рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░ рдХрд╛ std :: рдЕрдкрд╡рд╛рдж_ptr рд╣реИ ред рдорд╛рдирдХ рдореЗрдВ рдкреНрд░рдХрд╛рд░ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЦреБрд▓рд╛рд╕рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдкреНрд░рддрд┐ рдЕрдкрд╡рд╛рдж рд╡рд╕реНрддреБ рдХреЗ рд▓рд┐рдП рд╕рд╛рдЭрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рдлрд┐рд░ рдЗрди рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреИрд╕реЗ? рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди std :: rethrow_exception () рд╣реИ , рдЬреЛ рдПрдХ рдкреЙрдЗрдВрдЯрд░ std :: рдЕрдкрд╡рд╛рдж_ptr рд▓реЗрддрд╛ рд╣реИ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХрддрд╛ рд╣реИред рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдЗрд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХреИрдЪ рд╕реЗрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдкрдХрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдЗрд╕реЗ рдкреНрд░реЛрд╕реЗрд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рд╣рдо рдЕрдЧрд▓реЗ рдЕрдкрд╡рд╛рдж рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред


 using exceptions_queue = std::stack<std::exception_ptr>; // Get exceptions queue for current thread exceptions_queue& get_queue() { thread_local exceptions_queue queue_; return queue_; } // Invoke functor and save exception in queue void safe_invoke(std::function<void()> f) noexcept { try { f(); } catch (...) { get_queue().push(std::current_exception()); } } class ThrowInDestructor { public: ~ThrowInDestructor() noexcept { std::cerr << "~ThrowInDestructor() invoked\n"; safe_invoke([]() { throw_int_func(); }); } private: PrintInDestructor member_; }; int main(int, char**) { safe_invoke([]() { ThrowInDestructor bad; throw "BANG!"; }); auto& q = get_queue(); while (!q.empty()) { try { std::exception_ptr ex = q.top(); q.pop(); if (ex != nullptr) { std::rethrow_exception(ex); } } catch (int i) { std::cerr << "Catched int exception: " << i << "\n"; } catch (const char* s) { std::cerr << "Catched const char* exception: " << s << "\n"; } catch (...) { std::cerr << "Catched unknown exception\n"; } } return 0; } 

рдкрд░рд┐рдгрд╛рдо:


 ~ThrowInDestructor() invoked throw_int_func() invoked ~PrintInDestructor() invoked Catched const char* exception: BANG! Catched int exception: 1 

рдКрдкрд░ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╕реНрдЯреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдкрд╡рд╛рдж рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд┐рдВрдЧ FIFO рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ (рдЕрд░реНрдерд╛рдд, рддрд╛рд░реНрдХрд┐рдХ рд░реВрдк рд╕реЗ рдпрд╣ рдХрддрд╛рд░ рд╣реИ - рдкрд╣рд▓реЗ рдлреЗрдВрдХрд╛ рдЧрдпрд╛ рдЕрдкрд╡рд╛рдж рд╕рдВрд╕рд╛рдзрд┐рдд рд╣реЛрдиреЗ рд╡рд╛рд▓рд╛ рдкрд╣рд▓рд╛ рд╣реЛрдЧрд╛)ред


рдирд┐рд╖реНрдХрд░реНрд╖


рдСрдмреНрдЬреЗрдХреНрдЯ рдбрд┐рд╕реНрдЯреНрд░рдХреНрдЯрд░реНрд╕ рдореЗрдВ рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рдлреЗрдВрдХрдирд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдмреБрд░рд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ, рдФрд░ рдХрд┐рд╕реА рднреА рдирдП рдХреЛрдб рдореЗрдВ рдореИрдВ рджреГрдврд╝рддрд╛ рд╕реЗ noexcept рдбрд┐рд╕реНрдЯреНрд░рдХреНрдЯрд░реНрд╕ рдШреЛрд╖рд┐рдд рдХрд░рдХреЗ рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╡рд┐рд░рд╛рд╕рдд-рд╕рдВрд╣рд┐рддрд╛ рдХреЗ рд╕рдорд░реНрдерди рдФрд░ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рд╕рд╛рде, рд╡рд┐рдзреНрд╡рдВрд╕рдХ рд╕реЗ рдлреЗрдВрдХреЗ рдЧрдП рдЕрдкрд╡рд╛рджреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рдВрднрд╛рд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕реНрдЯреИрдХ рдкреНрд░рдореЛрд╢рди рдХреЗ рджреМрд░рд╛рди рднреА рд╢рд╛рдорд┐рд▓ рд╣реИ, рдФрд░ рдЖрдзреБрдирд┐рдХ рд╕реА ++ рд╣рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рддрдВрддреНрд░ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рд▓реЗрдЦ рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рд╡рд┐рдЪрд╛рд░ рдЗрд╕ рдХрдард┐рди рд░рд╛рд╕реНрддреЗ рдкрд░ рдЖрдкрдХреА рдорджрдж рдХрд░реЗрдВрдЧреЗред


рд╕рдВрджрд░реНрдн


рд▓реЗрдЦ рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рднрдВрдбрд╛рд░

Source: https://habr.com/ru/post/hi433944/


All Articles