1.요약
C++ 표준에는 exception이라는 상위 클래스가 있는데, MFC의 CException 과 같은 역할을 한다고 보시면 됩니다.
기본적은 exception 을 상속받는 클래스로서 bad_alloc, bad_cast, bad_typeid 등이 있는데, 이상하게도 Visual C++에는 bad_alloc 만 구현하지 않았습니다.
bad_alloc 은 new 가 실패했을때 던져지도록 약속된 Exception 클래스입니다.
여기서는 간단하기 bad_alloc을 구현해보겠습니다.
2.본문
우선 설명할 내용이 많지 않으므로 소스코드를 보여드리겠습니다.
#include <new.h>
#include <exception>
using namespace std;
class bad_alloc : public exception
{
public:
bad_alloc(const __exString& what_arg) : exception(what_arg) {}
};
int NewHandler(size_t size)
{
throw bad_alloc("Operator new couldn't allocate memory");
return 0;
}
int main(int argc, char* argv[])
{
_set_new_handler(NewHandler);
_set_new_mode(1); // use NewHandler for malloc as well
....
} 이전에 보여드렸던 예제와 크게 다른 점은 없습니다.
프로그램이 시작할 때( 혹은 각 스레드 엔트리의 처음에서) new handler를 설치해야합니다.
그리고 _set_new_mode(1); 을 호출함으로써 malloc 역시 new 와 같이 동작하다록 만들 수 있습니다.
보너스로 Exception을 잡으실때(catch) 유의하실 점을 몇가지 적어보겠습니다.
1. Non-MFC C++ exception 이라면 reference 를 사용하시는 게 좋습니다.
이렇게 말이죠.
try {
throw MyException();
}
catch(MyException& e)
{
} 이유는 간단합니다. 포인터를 사용한다면 객체를 동적으로 생성/소멸 시키는 루틴이 부가적으로 포함되어야 하기 때문에 안좋을테고, 그냥 MyException 을 사용한다면 추가적인 객체가 생성되고 복사생성자/소멸자가 추가적으로 호출될테니 비효율적이겠죠.
(참고적으로 dangling reference는 걱정하지 않으셔도 됩니다)
2. MFC exception 이라면 pointer를 사용해서 잡고, 반드시 Delete() 를 호출해주어야 합니다.
주의할 점으로는 절대 delete 를 사용해서 해제시켜서는 안됩니다. exception이 static object인 경우도 있기 때문입니다.
|