테스트 코드 작성으로 this query에 대한 답을 얻은 후에 개인/보호 된 상속이 다양한 클래스에서 예외가 수신되는 방식을 변경한다는 사실을 알아야합니다. 이는 매우 놀랍습니다. 답변을 찾으려면 이전 포럼 질문을 참조했고 나는 this similar question을 발견했습니다.상속이 예외 처리에 영향을주는 이유는 무엇입니까?
제게는 virtual
메서드를 사용하여 기본 클래스에 protected
상속을 사용하는 것이 명백합니다. 표준을 제쳐두고, 나는 을 알고 싶었습니다. 왜 가상 메소드 호출이 일 때 C++ 예외 처리가 상속으로 제한 되었습니까? 다음 코드는 설명 :
struct Base { virtual void printError() = 0; };
class Derived : protected Base { void printError() { } };
int main()
{
try {
throw new Derived;
}
catch(Base *p) { p->printError(); } // Ideal; but not invoked
catch(void *p) { ((Base*)p)->printError(); } // Ugly; but only way to invoke
}
편집 : 우리가 답변으로 개인 정보 보호 관련을 고려하면, 받아 들였다. 그렇다면 기본 포인터를 수신하는 함수에는 적용 할 수 없지만 기본 포인터를 수신하는 경우에만 catch()
을 적용해야하는 이유는 무엇입니까?
+1 좋은 질문입니다. – Nawaz
사소한 일로,'throw' 문에'new'를 사용할 필요가 없기 때문에 그렇게하면 메모리 누수가 발생할 위험이 있습니다. 대신에'throw Derived();'를 사용하고'Base &'참조를 잡아라. 또한, 분명히 왜 나에게 누군가가'protected' 상속을 사용하는지 분명하지 않습니다. 기본 클래스가 가상 메소드를 가지고 있다면, 당신이 뭔가 잘못 생각한 것 같아요. 그리고 마지막으로, 예외 클래스는 일반적으로'std :: exception'을 상속해야합니다. overload'char const * what() const'. –
@Matthieu, 감사합니다. 그러나 위 코드는 데모 목적으로 만 사용되었습니다. 'void '를 붙잡을 수 없으므로 참조에 의한 캐치는 불가능합니다. 그러나 나는 또한 참조로 잡는 것을 더 좋아한다. 내 디자인에 따라 인터페이스 (여기서는'Base') 클래스 메서드 (특히 가상)를 다른 네임 스페이스의 해당 자식에서 호출하면 안됩니다. – iammilind