이 질문은 here에서 따릅니다. 그러나, 이전의 질문은 나쁘게 (사실은 잘못) 말한 것이므로 처음부터 다시 묻는 것이 좋습니다.예외 안전 트램폴린을위한 디자인 패턴
나는 C- 함수 포인터 테이블을 가지고있다.
일부 C 코드 (lib-X라고 부름)에는 기본 구성 블록 (X-object라고 부름)이 있습니다. 각 X 객체는이 테이블에서 함수를 호출 할 수 있습니다.
이 테이블 함수는 일반적으로 여러 함수가 동일한 서명을 공유 할 수 있지만 다른 서명 (typedef here 참조)을 갖습니다. 이 테이블에는 약 100 가지 기능이 있습니다.
C++에서는 각 X- 개체에 대해 Final : Base 클래스가 연결되어 있습니다.
그리고이 호출을 X 객체의 해당 C++ Final 인스턴스에 전달하려고하지만 C++ 소비자가 버그가있는 Final을 제공 할 수 있으므로 try/catch 내에이 객체를 묶고 싶습니다.
그래서 테이블의 각 항목에 가상 함수가있는 C++ Base 클래스가 있습니다.
그런 다음 기본 클래스에서 파생 된 C++ 최종 클래스 (가능한 많은, 최종 1 결승 2 결승 3 등)가 있습니다.
그래서 지금은 단지
(항상 함수를 호출 한 X-개체에 대한 포인터 될 것입니다)
는 첫 번째 '자기'매개 변수를 가져옵니다하는 핸들러를 작성해야 연관된 C++ 기본 클래스 인스턴스를 검색합니다. 시도의 catch 블록 내에서
- 실제로 최종의 재정의를 호출 할 ...
를 통해 남아있는 모든 매개 변수를 전달, 해당 가상 함수를 호출합니다.
처음 시작에 대한 플롯을 이해하려고하는 것처럼 보입니다. lib-X는 사실 Python 런타임입니다. 비록 일반적인 것을 유지하려고 노력하고 있습니다.
것은 이러한 기능 수십개가 있으며, 이것은 매우 지저분하고 유지 보수가 어려운 C++ 코드를 만든다 - 나는 수동처럼 보이는, 각각에 대해 트램 폴린 함수를 작성해야하는 경우 :
extern "C" PyObject *call_handler(PyObject *self, PyObject *args, PyObject *kw)
{
try
{
PythonExtensionBase *p = getPythonExtensionBase(self);
if(kw != NULL)
return new_reference_to(p->call(Object(args), :Object(kw)));
else
return new_reference_to(p->call(Object(args), Object()));
}
catch(Py::Exception &)
{
return NULL; // indicate error
}
}
(소스 here)
저는이 예외없는 안전한 트램 폴리 라인을 허용하는 컴팩트 한 디자인을 제시하려고합니다.
내 진행 상황은 [제거됨, 아래 답변 참조]
(); '바닥 ("EDIT")에 연결된 코드 샘플입니다. – dyp
@dyp, ARGH! 감사! (지금 버려진 코드는 제거되었습니다) –
틀릴 수도 있지만 NVI (비 가상 인터페이스) 관용구가 이것을 해결하지 않았습니까? 기본 클래스에는 보호 된 도우미에게 전달하는 공개 비회원 메서드가 있습니다. 가상이 아닌 메소드는 try/catch 코드를 매우 편리하게 볼 수 있습니다. – Mark