티스토리 뷰

소멸자로부터 예외가 터져 나가는 경우를 C++ 언어에서 막는 것은 아니지만, 실제 상황을 들춰보면 확실히 우리가 막을 수밖에 없는 것 같습니다. 예를 들어 보죠.

 

class Widget{
public:
	~ Widget(){ } //이 함수로부터 예외가 발생합니다.
};

void doSometing()
{
	std::vector<Widget> v;
    ...
}				// v는 여기서 자동으로 소멸됩니다.

다음과 같은 상황에서 백터 v가 10개라고 가정하였을 때, 함수가 끝나고 소멸하게 되는데 이때 첫 번째 객체에서 소멸자가에서 오류가 발생한 이후, 또 다시 두 번째 객체에서 소멸자에서 오류가 발생하게 되면, 두개의 예외가 동시에 만들어진 상태입니다. 그렇게 되면 프로그램이 터지던지 정의되지 않은 행동을 보일텐데 이때는 정의되지 않는 행동을 보이게 됩니다.

 

이런 상황에 try catch문을 사용할 수도 있습니다. 예외 삼키기의 경우, 예외가 후에 있을 프로그램에 지장이 가지 않는다면 가능한 상황에서 사용할 수 있습니다.

class DBConn{
public:
	...
    ~DBConn(){
    	try { db.close(); }
        catch(...){
        	close 호출이 실패했다는 로그 출력
            std::abort();
            // 프로그램 종료
        }
    }
}

class DBConn{
public:
	...
    ~DBConn(){
    	try { db.close(); }
        catch(...){
        	close 호출이 실패했다는 로그 출력
            // 예외 삼키기
        }
    }
}

 

그렇지 않다면 다른 함수를 통해 종료를 하여야 합니다. 왜냐하면 '소멸자' 안에서는 오류가 발생하면 안되기 때문이죠.

이 형태는 사용자에게 종료를 맡기는 형태이죠.

class DBConn{
public:
	...
    void Close(){
    	db.close();
        closed = true;
    }
    ~DBConn(){
    	if(!closed)
        try{ db.close(); }
        catch(...)
        {
            close 호출이 실패했다는 로그 출력
            std::abort();
        }
    }
}

 

※ 소멸자에서 예외가 빠져나가면 안 됩니다. 만약 소멸자 안에서 호출된 함수가 예외를 던질 가능성이 있다면, 어떤 예외이든지 소멸자에서 모두 받아낸 후에 삼켜 버리든지 프로그램을 끝내든지 해야 합니다.

 

※ 어떤 클래스의 연산이 진행되다가 던진 예외에 대해 사용자가 반응해야 할 필요가 있다면, 해당 연산을 제공하는 함수는 반드시 보통의 함수(즉, 소멸자가 아닌 함수)이어야 합니다.

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함