A를 생성하는 동안 예외가 발생하면 소멸자가 이 아닌이 호출됩니다.
분명히 해결책은 당신이하고있는 것에 달려 있지만, 이상적으로는 에이 없으므로 정리할 필요가 없습니다. RAII을 활용해야하며, 반원들이 직접 청소해야합니다.
즉, 원시 포인터를 사용하지 마십시오. 그들을 감싸서 래퍼가 처리하도록하십시오. 놀람! C++ 프로그래머는 당신과 마찬가지로 메모리 관리를 싫어합니다. 우리는 그것을 감싸고 잊어 버리고 싶어합니다.
당신이 진정으로하지만, 나는 이것이 일반적인 생각해야하는 경우 :
struct foo
{
int* i;
some_member_that_could_throw crap;
foo() // do *not* new i! if the second member throws, memory is leaked.
{ // rather:
// okay we made it, the other member must have initialized
i = new int;
}
};
이 포인터에 관하여,이 값의 변경되지 않습니다.
new
이 어떤 이유로 든 예외를 throw하면 스택이 해제됩니다. 표현의 나머지 부분은 버려졌습니다.
다음은 예외 및 개체 생성의 작동 방식입니다. 재귀 적 프로세스입니다. 각 멤버 또는 기본 클래스가이 목록을 차례로 따르기 때문입니다. 기본 유형에는 생성자가 없습니다. 이것은 재귀에 대한 기본 사례입니다.
- 먼저 각 기본 클래스를 구성하십시오. 이 목록을 차례로 실행하십시오.
- 클래스 구성원을 하나씩 초기화하십시오.
- 생성자 본문을 실행하십시오.
- 완벽하게 구성된 개체로 마무리하십시오.
분명히, 항목 1이 실패하면 우리 회원 중 누구도 초기화되지 않았으므로 우리가해야 할 정리가 없습니다. 우린 잘 했어.
두 가지가 다릅니다. 그 중 하나가 실패 할 경우 초기화 된 멤버 은 지금까지이 파괴되고 생성자가 진행을 멈추고 예외는 메리 방식으로 진행됩니다. 이것은 회원들이 스스로를 정리할 때 걱정할 것이없는 이유입니다. 초기화되지 않은 함수는 아무 것도하지 않으며, 초기화 된 함수는 소멸자가 실행되어 정리가 수행됩니다.
3 명이 더 그렇습니다.개체가 완전히 초기화되었으므로 이제는 소멸자가 모두 실행됩니다. 다시 말하지만 걱정하지 않아도됩니다.
try
{
// some code
}
catch (..) // catch whatever
{
delete myrawPointer; // stop the leak!
throw; // and let the exception continue
}
그것은 RAII없이 예외 안전한 코드를 작성하기가 훨씬 더 지저분가 : 당신 주위에 거짓말을 원시 포인터가있는 경우 그러나,이 try/catch 블록을위한 시간이다.
무엇이 RAII입니까? 당신은 정교 할 수 있습니까? –
@ 지미 장 : http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization –
그래서 생성자에서 try/catch를 수행하지 말고 A의 생성자에서 B 및 C에 대한 소멸자를 호출하지 않는 것이 좋습니다 예외? –