ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 소멸자에서 예외를 발생?
    @ 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번 방법도 좋을때가 있다 그 전제는 예를 무시해도 프로그램이 정상적으로 작동된다면 말이다.

     

     

     

Designed by Tistory.