[Effective C++] 항목 8 : 예외가 소멸자를 떠나지 못하도록 붙들어 놓자

수민이슈·2023년 3월 16일
0

Effective C++

목록 보기
8/30
post-thumbnail

스콧 마이어스의 Effective C++을 읽고 개인 공부 목적으로 요약 작성한 글입니다!

💡 소멸자에서는 예외가 빠져나가면 안된다!
💡 소멸자 안에서 호출된 함수가 예외를 던질 가능성이 있다면, 어떤 예외든 소멸자에서 모두 받아낸 후 삼키던지, 프로그램을 끝내든 해야 한다.
💡 어떤 클래스의 연산이 진행되다가 던진 예외에 대해 사용자가 반응해야 할 필요가 있다면,
해당 연산을 제공하는 함수는 소멸자가 아니어야 한다.


🖊️ 소멸자에서 예외 발생?

벡터를 소멸한다 쳤을 때,,
첫 번째 원소와 두 번째 원소의 소멸자에서 예외가 던져지면?

예외에 따라 프로그램의 실행이 종료되거나, 정의되지 않은 동작을 보일거다.

class DBConnection {
public:
	...
    static DBConnection create();
    
    void close();			// 여기서 연결을 닫고, 실패 시 예외 반환
};

이런 클래스가 있다 쳤을 때, 그러면 사용자가 매번 직접 close 해줘야 함.

class DBConn {
public:
	...
    ~DBConn() {
    	db.close();
    }
private:
	DBConnection db;
};

DBConnection 클래스를 관리해주는 DBConn 클래스를 만든다.
그래서 DBConn 클래스의 소멸자에서 close를 해준다.

근데 만약 예외가 생긴다면,

DBConn의 소멸자는 예외를 리턴할거다.

  1. abort()를 호출해서 프로그램을 종료시키거나
  2. 예외를 삼켜버린다

예외를 삼키면, 무엇이 잘못됐는지 알려주는 정보가 묻힌다
but 프로그램의 종료나 미정의 동작보다는 그게 낫기도 하다.
(물론 이런 경우 예외를 삼키는 선택을 하면, 프로그램이 신뢰성있게 실행을 지속할 수 있어야 함)

근데 그러면,, 예외를 어떻게 처리할지 모르잖아
걍 방관임

좋은 방법 없을까?

문제가 발생할 소지가 있다면, 그걸 사용자가 대처할 수 있도록 하면 어떠니?
DBConn에서 close함수를 직접 제공하게 한다면?

class DBConn {
public:
	...
    void close() {
    	db.close();
        closed = true;
    }
    
    ~DBConn() {
      if (!closed)
      try {
          db.close();
      }
      catch (...) {
          // close 호출이 실패했다는 로그 작성
      }
    }
private:
	DBConnection db;
    bool closed;
};

그니까 DBConn의 소멸자에서 close를 호출하기 전에,
사용자가 close할 수 있는 기회를 준다.
사용자가 close()를 호출하면, 거기서 발생한 오류를 처리할 기회가 생긴다.
소멸자에서 하면 손을 쓸 수가 없거등

여기까지 했는데도 close에서 안해서 소멸자에서 예외가 발생하든 말든..
쨋든 기회를 주긴 준거임.

😊 느낀점

사용자에게 하라고 하고,
만약에 사용자가 안했으면 소멸자에서 처리하게 하는게 좋은 방법인 것 같다
이렇게 새로운걸 배워가유

0개의 댓글