CppModule 05

05

main thema : ์˜ˆ์™ธ์ฒ˜๋ฆฌ.

https://www.youtube.com/watch?v=tTG-VrkLRpk

https://wikidocs.net/29948

1. ์˜ˆ์™ธ ๊ฐœ๋…

1.1 ์˜ˆ์™ธ๋ž€

Exceptions are run-time anomalies(such as losing a database connection or encountering unexpected input)that exist outside the normal functioning of a program. Dealing with anomalous behavior can be one of the most difficult parts of designing any system. -c++ primer 5th-

๋Ÿฐํƒ€์ž„์— ์™ธ๋ถ€์— ์˜ํ•ด ๋ฐœ์ƒํ•œ ์˜๋„ํ•œ ๊ธฐ๋Šฅ ์ด์™ธ์˜ ๋™์ž‘๋“ค์ด๋‹ค. ์™ธ๋ถ€์˜ ์š”์ธ์— ์˜ํ•ด ๋ฐ์ด์Šค์˜ ์—ฐ๊ฒฐ์ด ๊ฐ‘์ž๊ธฐ ๋Š๊ธด๋‹ค๋˜์ง€, ๊ทœ๊ฒฉ ์™ธ์˜ ์ž…๋ ฅ ๋“ฑ์ด ์žˆ๋‹ค. (๋ˆ„์ˆ˜๋‚˜ ์„ธ๊ทธํดํŠธ๋Š” ๋‚ด๋ถ€์ ์ธ ๋ฌธ์ œ์ด๋ฏ€๋กœ ์—๋Ÿฌ์ด๋‹ค)

1.2 ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ž€

Exception handling is generally used when one part of a program detects a problem that it cannot resolve and the problem is such that the detecting part of the program cannot continue. In such cases, the detecting part needs a way to signal that something happened and that it cannot continue. Moreover, the detecting part needs a way to signal the problem without knowing what part of the program will deal with the exceptional condition. Having signaled what happened, the detecting part stops processing. -c++ primer 5th-

์œ„์™€ ๊ฐ™์€ ์˜ˆ์™ธ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ , ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ์‹ ํ˜ธ๋ฅผ ๋ณด๋‚ด๊ณ  ๋™์ž‘ํ• ์ง€ ์ •ํ•˜๋Š”๊ฒƒ์ด ์˜ˆ์™ธ ์ฒ˜๋ฆฌ์ด๋‹ค.

2 ์˜ˆ์™ธ์ฒ˜๋ฆฌ์— ํ•„์š”ํ•œ ์š”์†Œ๋“ค.

2.1 throw

์˜ˆ์™ธ๋ฅผ ๊ฐ์ง€ํ•˜๋Š”๊ฑด if๋ฌธ ๋“ฑ ์กฐ๊ฑด๋ฌธ์„ ํ†ตํ•ด ํ™•์ธ์„ ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋ฅผ ๋˜์งˆ๋•Œ๋Š” throw()ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

// ์˜ˆ์™ธ ๋ช…์„ธ : ์–ด๋–ค ์˜ˆ์™ธ๋ฅผ ๋˜์งˆ์ง€ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ. 
// throw()        : ์˜ˆ์™ธ ์—†์Œ -> c++11๋ถ€ํ„ฐ๋Š” noexcept์‚ฌ์šฉ.
// throw(ํด๋ž˜์Šค)  : ํ•ด๋‹น ํด๋ž˜์Šค์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ์ฒด ์ธ์Šคํ„ด์Šคํ™” ํ•˜์—ฌ throw.
// ์ด ํ•จ์ˆ˜๋Š” std::exception์ค‘ ํ•˜๋‚˜๋ฅผ ๋˜์งˆ๊ฒƒ์ด๋‹ค. std::exception์˜ ๊ฒฝ์šฐ ๋‹คํ˜•์„ฑ์ด ์‚ฌ์šฉ๋จ.
void func1() throw (std::exception)
{
   ...
   // std::exception๋ฅผ ์ƒ์†? ๊ตฌํ˜„? ํ™•์žฅ? ํ•œ ์ปค์Šคํ…€ std์˜ˆ์™ธ์˜ ์ƒ์„ฑ์ž ํ˜ธ์ถœ.
   throw (CustonStdException());
}

throw๊ฐ€ ๋ฐœ์ƒํ•œ ์ดํ›„์˜ ์ฝ”๋“œ๋Š” ์ „๋ถ€ ์ˆ˜ํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค(throwํ•œ ํ•จ์ˆ˜ ๋ฐ–์—์„œ๋„). ์ด์™€ ๊ด€๋ จ๋œ ๋‚ด์šฉ์€ ์Šคํƒ ํ’€๊ธฐ(Stack Unwinding) ๊ฒ€์ƒ‰.

2.2 try catch

์œ„์—์„œ ๋˜์ง„ ์˜ˆ์™ธ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ›์•„์„œ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ถ€๋ถ„์ด try-catch๋ฌธ์ด๋‹ค.

try
{
   ...
   func1(); // ์˜ˆ์™ธ ๋ฐœ์ƒ
   // ์˜ˆ์™ธ ๋ฐœ์ƒ์‹œ, try๋‚ด๋ถ€ ์ดํ›„์˜ ์ฝ”๋“œ๋Š” ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค.
}
catch(std::exception& e)
{
   // ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ ํ‘œ์‹œ
   std::cerr << e.what() << '\n';
}

try๋กœ ๋ฌถ๋Š” ๊ธฐ์ค€ : ์˜ˆ์™ธ๋ฌธ๋งŒ ๋„ฃ์„๊ฒŒ ์•„๋‹ˆ๋ผ, ์ด์™€ ๊ด€๋ จ๋œ ๋ชจ๋“  ์ž‘์—…์„ ๋‹ค ๋„ฃ์–ด์„œ ๊ด€๋ จ๋œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ์™€ ๊ด€๋ จ๋œ ๋ชจ๋“ ๊ฒƒ๋“ค์ด ์ฒ˜๋ฆฌ๋˜์–ด์•ผํ•œ๋‹ค.

ํ‘œ์ค€ ์—๋Ÿฌ ํด๋ž˜์Šค ์œ ์ €? ์—๋Ÿฌ ํด๋ž˜์Šค

ex00

๋ชฉ์  : ํ‘œ์ค€ ์˜ˆ์™ธ ํด๋ž˜์Šค ์ƒ์„ฑ ๋ฐ ์‚ฌ์šฉ.

In file included from Bureaucrat.cpp:3:
./Bureaucrat.hpp:26:8: error: exception specification of overriding function is more lax than base version
        class GradeTooHighException: public std::exception
              ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/exception:101:13: note: overridden virtual function is here
    virtual ~exception() _NOEXCEPT;
            ^
...
class _LIBCPP_EXCEPTION_ABI exception
{
public:
    _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {}
    virtual ~exception() _NOEXCEPT;
    virtual const char* what() const _NOEXCEPT;
};

์—ํ”Œ์—์„œ exceptionํด๋ž˜์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋˜์–ด์žˆ๋‹ค.

c++์—์„œ ํด๋ž˜์Šค์˜ ์†Œ๋ฉธ์ž๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ƒ์„œํ•˜์ง€ ์•Š์œผ๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๊ณ , ์ด๋•Œ ์†Œ๋ฉธ์ž๊ฐ€ noexcpet(๊ตฌ throw())ํ˜•ํƒœ๋กœ ์ƒ์„ฑํ•ด์ฃผ์ง€ ์•Š์•„์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๊ฑธ๋กœ ๋ณด์ธ๋‹ค.

This isnโ€™t telling the whole story. Compiler generated destructor will have a nothrow specification if all the functions it directly invokes allow no exceptions (destructors of non-static data members and destructors of base classes). The example fails to compile because std::string memberโ€™s destructor isnโ€™t marked throw(). Try replacing it with const char* and see the difference. โ€“ jrok Aug 24, 2013 at 9:54

stackoverflow

์Šคํƒ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ์— ๋”ฐ๋ฅด๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์•”์‹œ์ ์œผ๋กœ ์†Œ๋ฉธ์ž๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, ๋งด๋ฒ„๋“ค์ด noexcept(throw())๊ฐ€ ๋ณด์žฅ๋ ๋•Œ noexcept(true)๋กœ ์ƒ์„ฑ๋œ๋‹ค.

  1. Bureaucrat ํด๋ž˜์Šค์˜ ๋งด๋ฒ„ ์ค‘์— std::stringํ˜•์ธ ๋งด๋ฒ„ ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋‹ค.
  2. ์†Œ๋ฉธ์ž๋ฅผ ํ˜ธ์ถœํ• ๋•Œ ํ˜ธ์ถœ๋  std::string์˜ ์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
  3. ๊ทธ๋Ÿฌ๋‚˜ std::string์˜ ์†Œ๋ฉธ์ž๋Š” noexcept(true)๊ฐ€ ์•„๋‹ˆ๋‹ค(๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค).
  4. ๋”ฐ๋ผ์„œ Bureaucrat ํด๋ž˜์Šค์˜ ์†Œ๋ฉธ์ž๋ฅผ ์•”์‹œ์ ์œผ๋กœ ์ƒ์„ฑํ• ๋•Œ noexcept(true)๋ฅผ ํ•˜์ง€ ์•Š์•„์„œ ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

std::string์„ const char *ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.