그래서 내 질문은 이것입니다-소멸자에서 던지면 정의되지 않은 동작이 발생하면 소멸자 중에 발생하는 오류를 어떻게 처리합니까?
주요 문제는 이것입니다 : 당신은 실패 할 수 없습니다 . 결국 실패하지 못한다는 것은 무엇을 의미합니까? 트랜잭션을 데이터베이스에 커밋하는 데 실패하고 실패 (롤백 실패)하면 데이터의 무결성은 어떻게됩니까?
소멸자는 일반적인 경로와 예외적 인 (실패한) 경로 모두에 대해 호출되므로 스스로 실패 할 수 없거나 "실패하지 못합니다".
이것은 개념적으로 어려운 문제이지만 종종 해결책은 실패가 실패하지 않도록하는 방법을 찾는 것입니다. 예를 들어 데이터베이스는 외부 데이터 구조 또는 파일을 커밋하기 전에 변경 사항을 쓸 수 있습니다. 트랜잭션이 실패하면 파일 / 데이터 구조를 버릴 수 있습니다. 그러면 외부 구조 / 파일에서 변경 사항을 커밋해도 실패하지 않는 원자 트랜잭션을 보장 할 수 있습니다.
실용적 해결책은 실패에 실패하는 것을 불가능하게 만드는 것이 거의 불가능할 수 있기 때문에 실패에 실패 할 가능성을 천문학적으로 불가능하게 만드는 것입니다.
나에게 가장 적합한 해결책은 정리 논리가 실패하지 않는 방식으로 비 정리 논리를 작성하는 것입니다. 예를 들어, 기존의 데이터 구조를 정리하기 위해 새로운 데이터 구조를 만들고 싶은 경우, 더 이상 소멸자 내부에서 생성 할 필요가 없도록 해당 보조 구조를 미리 만들 수 있습니다.
이것은 분명히 말한 것보다 훨씬 쉽지만, 그것에 관해 내가 보는 유일한 방법입니다. 때로는 예외적 인 경로에서 멀리 떨어져있는 일반적인 실행 경로에 대해 별도의 소멸자 논리를 작성하는 기능이 있어야한다고 생각합니다. 파괴자가 두 가지를 모두 처리하여 책임을 두 배로 느끼는 것처럼 느껴지기 때문에 (예 : 명시 적 해고가 필요한 스코프 가드) 예외적 인 경로와 예외가 아닌 경로를 구별 할 수 있다면이를 필요로하지 않을 것입니다).
여전히 궁극적 인 문제는 우리가 실패 할 수 없다는 것입니다. 모든 경우에 완벽하게 해결하는 것은 어려운 개념 설계 문제입니다. 복잡한 물체가 서로 상호 작용하는 복잡한 제어 구조로 너무 복잡하게 싸이 지 않고 약간 더 큰 방식으로 설계를 모델링하는 것이 더 쉽습니다 (예 : 전체 입자를 파괴하는 소멸자가있는 입자 시스템) 파티클 당 별도의 소멸자가 아닌 시스템). 이런 종류의 거친 수준에서 디자인을 모델링 할 때 다루기 어려운 소멸자가 적고 소멸자가 실패하지 않도록 메모리 / 프로세싱 오버 헤드가 필요한 경우가 종종 있습니다.
그리고 자연스럽게 가장 쉬운 해결책 중 하나는 소멸자를 덜 자주 사용하는 것입니다. 위의 입자 예에서, 아마도 입자를 파괴 / 제거 할 때 어떤 이유로 든 실패 할 수있는 몇 가지 작업을 수행해야합니다. 이 경우 예외 경로에서 실행될 수있는 입자의 dtor를 통해 이러한 논리를 호출하는 대신 입자를 제거 할 때 입자 시스템에서 모두 수행 할 수 있습니다 . 예외가 아닌 경로에서 항상 입자 제거가 수행 될 수 있습니다. 시스템이 파괴되면 모든 파티클을 제거하고 실패 할 수있는 개별 파티클 제거 로직을 방해하지 않을 수 있지만 실패 할 수있는 로직은 하나 이상의 파티클을 제거 할 때 파티클 시스템의 정상적인 실행 중에 만 실행됩니다.
사소한 소멸자가 아닌 많은 작은 물체를 다루지 않으면 자라는 솔루션과 같은 솔루션이 종종 있습니다. 예외 안전이 거의 불가능 해 보이는 혼란에 빠질 수있는 곳은 모두 사소한 dtor가있는 많은 작은 물건에 얽힌 경우입니다.
nothrow / noexcept가 실제로 그것을 지정하는 것 (기본 클래스의 noexcept 사양을 상속 해야하는 가상 함수 포함)이 던질 수있는 것을 호출하려고 시도하면 실제로 컴파일러 오류로 변환되면 많은 도움이 될 것입니다. 이렇게하면 실수로 던질 수있는 소멸자를 실제로 작성하면 컴파일 타임 에이 모든 것을 잡을 수 있습니다.