본문 바로가기
Book & Lecture/Effective C++

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

by studio ODOC 2023. 2. 6.
반응형

Effective C++ 항목8

 예외가 소멸자를 떠나지 못하도록 붙들어 놓자

  • 클래스의 인스턴트, 즉 객체가 소멸할 때 각종 예외를 처리할 수 있다.
class DBConnection
{
  public:
    ...
    static DBConnection create();
    void close();
};

class DBConn // DBConnection 객체를 관리하는 클래스
{
  public:
    ...
    ~DBConn() { db.close(); } // 데이터베이스 연결이 항상 닫히도록
    						  // 확실히 챙겨주는 함수
  private:
    DBConnection db;
};
  • 소멸자의 db.close()에서 예외가 발생할 수 있음. 대응책은?
    • 1) 프로그램을 바로 끝내버림. abort()호출
DBConn::~DBConn()
{
	try {db.close(); }
	catch (...) {
 		std::abort; // 프로그램 바로 끝내버림
 	}
}
  • 2) 예외를 삼켜버림. try, catch만 하고 별도의 함수 콜은 안함
    • 이 경우, 예외를 무시했을지라도 이후에 프로그램이 신뢰성 있게 실행을 지속할 수 있어야 함
DBConn::~DBConn()
{
	try {db.close(); }
	catch (...) {
    	// 별도 처리 안함
 	}
}
  • 위 예외처리의 더 좋은 전략?
    • bool형의 closed변수를 두어, 연결이 제대로 close되었는지의 유무 저장하는 정도..
    • close()함수를 보통 함수(소멸자가 아닌 함수)로 두어, 사용자에게 칼자루를 넘기자
class DBConn
{
  public:
  ...
  // 사용자 호출을 배려(?) 해서 새로 만든 함수
  // 사용자가 예외처리를 제대로 하지 못하더라도 칼자루는 사용자에게 있음..
  void close()
  {
    db.close();
    closed = true;
  }

  
  ~DBConn()
  {
    if (!closed)
    try {
    	db.close(); // 사용자가 연결을 안 닫았으면 여기서 close시도
    }
    catch (...) {
    	// 실패하면 프로그램을 끝내버리거나(abort) 예외를 삼키기
    }
  }
  . . .
};
반응형