-
소멸자에서 예외를 발생?@ 16. 1 ~ 17. 1/Effective C++ 2015. 12. 5. 16:06
소멸자에서 예외를 발생시킬 수 있는 클래스가 있다.
이게 무슨 상황이냐면..
아래와 같은 클래스가 하나있다..
class DBConnection { public: static DBConnection create(); //DBConnection 객체를 반환하는 함수. void close(); //연결을 닫습니다, 이떄 실패하면 예외를 던짐 };
보면 사용자가 DBConnetion 객체에 대해 close를 직접 호출해야하는 설계이다.(close는 종료를 뜻하지)
사용자의 망각을 사전에 차단하는 좋은 방법이라면 DBConnection에 대한 자원 관리 클래스를 만들어서 그 클래스의 소멸자에서 close를 호출하게 하면 된다!
아래 처럼!
class DBConn //DBConnection 객체를 관리하는 클래스 { private: DBConnection db; public: ~DBConn() { db.close(); //연결이 항상 닫히도록 확실하게 챙겨주는 함수 } }; DBConn dbc(DBConnection::create()); //DBConnection 객체를 생성하고 이것을 DBConn객체로 념거서 관리한다. //즉 DBConn 인터페이스를 통해 그 DBConnection객체를 사용합니다. 그리고 사용이 끝나면 //자동으로 소멸자가 호출되고 DBConnection의 close()함수가 자동 호출된다.
close호출만 일사천리로 성공하면 아무 문제될 것이 없는 코드다. 그러나 close를 호출했는데 여ㅣ서 예외가 발생했다면 하면??
DBConn의 소멸자는 분명히 이 예외를 전파하고 나가도록 내버려둔다. 이게 문제가 된다.
그래서 이 걱정거리를 피하는 방법은 2가지
1. close에서 예외가 발생하면 프로그램을 바로 끝낸다. (abort()함수 호출)
~DBConn() { try { db.close(); //연결이 항상 닫히도록 확실하게 챙겨주는 함수 } catch(...) { //close 호출이 실패했다는 로그를 기록하면 좋고.. std::abort(); } }
객체 소멸이 진행되다가 에러가 발생하고 프로그램 실행을 계속할 수 없다면 괜찮은 선택
불상사를 사전에 차단하는 의미에서 좋다.
2. close를 호출한 곳에서 일어난 예외를 삼켜버린다.
~DBConn() { try { db.close(); //연결이 항상 닫히도록 확실하게 챙겨주는 함수 } catch(...) { //close 호출이 실패했다는 로그를 기록하면 좋고.. } }
그러나 삼키는건 별로 좋지 못하다. 무엇이 잘못됐는지를 알려주지 않기 때문이다. 1번이 좋긴한데 2번 방법도 좋을때가 있다 그 전제는 예를 무시해도 프로그램이 정상적으로 작동된다면 말이다.
'@ 16. 1 ~ 17. 1 > Effective C++' 카테고리의 다른 글
인라인 함수 언제사용하지?? (0) 2015.12.31 기본 대입연산자 생성조건? (0) 2015.12.04 클래스 생성자는 초기화가 아니다. 정적(static)객체의 종류와 방법 (0) 2015.12.04 const 멤버 함수의 종류, const 함수내에서 수정가능한 경우 (0) 2015.12.04 #define cosnt 상수변수로 바꾸기! operator[], const static, 클래스내 const, define 매크로 (0) 2015.12.03