다음과 같은 간단한 상황이 도처에 나타납니다. 다음과 같은 함수 서명으로 많은 수의 요청이 기기에 제공됩니다.
Err execute( const ICommandContext &context,
const RoutineArguments &arguments,
RoutineResults &results)
본질적으로 이것을 호출하는 요청 처리 서버가 있으며 이러한 서명을 가진 다양한 요청 유형에 대해 함수를 실행합니다. 오류가 발생한 경우 2 개의 반환 경로가 있습니다.
<올>Err
와 동등한 것으로 간주하십시오.
)는 요청이 아닌 시스템과 관련하여 문제가 있음을 서버 나 시스템에 알리는 데 사용됩니다. 사용자 요청이 처리되기 전에 항상 함수 상단에 정렬됩니다.int
RoutineResults
를 제공합니다
요청의 실패 정보를 클라이언트에 반환하는 데 사용할 수있는 기능이러한 이유로 이런 유형의 코드가 많이 나타납니다 :
setStatus
우리는
// Failure due to request
Err error = someFunctionCall(clientInput);
if (!error.success()) {
results.setStatus(error); // Inform the client of the error
return SUCCESS; // Inform the system that we are all good
}
가있는 특정 요청 유형을 가지고 있습니다.
시스템으로 들어오고 나가는 매개 변수. 개념적으로이
15
의 15 개가 필요합니다
낭비처럼 보이는 세트. 또한 우리가 돌아가는 방법에 대해 무엇인가를 바꿔야 할 경우 오류가 발생하기 쉽습니다.Wyzwyz를 효과적으로 위임하는 방법
함수에서 한 번만 발생하면되는 짧은 양의 코드로 돌아가시겠습니까?
와이즈 비즈 시스템은 다음과 같은 매크로를 사용하여이 문제를 해결할 수 있습니다.
if error do
다음과 같이 사용될 것입니다 :
setStatus
이것은 코드를 깔끔하게 정리하지만 특히
c
에는 좋지 않습니다.
.
#define M_InitTry Err error
#define M_Try(statement) if (!(error = statement).success()) { goto catch_lab; }
#define M_Catch catch_lab: if (!error.successs())
#define M_Return return error
가 생략 할 수있는 변수를 정의하면 문제가 발생할 수 있습니다.
.
더 많은
Err execute( const ICommandContext &context, ...) {
M_InitTry;
...
M_Try(someFunctionCall(clientInput));
M_Try(someFunctionCall(otherClientInput));
...
M_Catch {
// Other specific actions for dealing with the return.
results.setStatus(error);
error = SUCCESS;
}
M_Return;
}
를 생각하고 있었다
그래서 RAII 유형 대의원이 도움이 될 것이라고 생각했습니다. 다음과 같은 것 :
goto
매우 간단합니다. 소멸자에서 작업을 구현하여 함수가 반환 될 때까지 작업을 위임합니다. 다음과 같이 사용할 수 있습니다 :
goto
실제 예 이 솔루션은 문제가 없지만 몇 가지 문제가 있습니다.
<올>C++
가 필요합니다
반품 처리에 대한 진술.이 문제는 자주 발생합니다. 이 세트의 명확한 위임을 제공하고 유형 조치를 리턴하는 일반적인 솔루션이 있습니까?
<시간>아래에 불행한 제한이 있습니다. 미래의 사람들에게 도움이 될 수 있으므로 응답하지 못하게하세요.
<올>class DelegateToFunctionEnd {
typedef std::function<void(void)> EndFunction;
public:
DelegateToFunctionEnd(EndFunction endFunction) : callAtEnd(endFunction) { }
~DelegateToFunctionEnd() {
callAtEnd();
}
private:
EndFunction callAtEnd;
};
이지만 c ++ 11은 없습니다.Err execute( const ICommandContext &context, ...) {
Err error;
DelegateToFunctionEnd del(std::bind(&RoutineResults::setStatus, &results, std::cref(error)));
error = someFunctionCall(clientInput));
if (error) return SUCCESS;
...
}
- 답변 # 1
- 답변 # 2
어쩌면 다음과 같은 문장을 배열로 작성할 수 있습니다 :
catch
다른 진술만으로 여러 번 그렇게하면 당신은 만들 수 있습니다
Err execute( const ICommandContext &context, ...) { const boost::function<Err()> functions[] = { boost::bind(&someFunctionCall, std::ref(clientInput)), boost::bind(&someFunctionCall, std::ref(otherClientInput)), // ... }; for (std::size_t i = 0; i != sizeof(functions) / sizeof(functions[0]); ++i) { Err err = functions[i](); if (!err.successs()) { results.setStatus(err); return SUCCESS; } } return SUCCESS; }
Err execute_functions(const ICommandContext &context, std::function<Err()> functions);
와 같은 다른 진입 점을 제공 할 수도 있습니다. 필요에 따라 - 답변 # 3
기능을 분리하십시오.
내부 함수는 사용자 입력에 따라 오류 코드를 반환합니다. 바깥 쪽은이를 클라이언트 오류로 변환하고 서버 측 오류 만 반환합니다.내부 함수는 다음을 포함합니다 :
OnError
반복적으로. 외부에는 클라이언트에 대한 릴레이 오류 코드가 있지만 한 번만 있습니다.
Err은 운영자 bool 만 있으면됩니다. 가질 수없는 경우 Err로 변환하거나 Err로 변환하고 연산자 bool이있는 유형을 작성하십시오.
- 답변 # 4
체크 등을 수행하는 오류에 메소드를 추가하고 bool을 리턴 할 수 있습니까?
if(Err error = someFunctionCall(clientInput)) return error;
if(!someFunctionCall(clientInput).handleSuccess(results)) { return SUCCESS; }
관련 자료
- c++ - 함수는 채우고있는 char 배열보다 큰 cstring을 어떻게 반환 할 수 있습니까?
- wordpress - functionsphp를 통해 applyFilters 함수가 false를 반환하도록 만드는 방법
- arrays - PHP 함수에서 한 번에 둘 이상의 값을 반환하는 방법
- sqlalchemy - 돌아온 다음 파이썬에서 다른 함수가 끝날 때까지 기다립니다
- c++ - 하위 시퀀스가 시작되는 첫 번째 반복자를 반환하는 STD 함수
- list - 왜 pop () 함수가 파이썬의 함수 내부에서 값을 반환하지 않습니까?
- recursion - 문자열을 반환하기 위해 Swift에서 재귀 함수를 어떻게 빌드 할 수 있습니까?
- promise - Nodejs 함수 비동기 반환 대기하지 않음
- Swift 함수에서 함수가 루프 내부에 if 문이있는 for 루프를 포함 할 때 왜 'return'이 for 루프 외부에 있어야합니까?
- c - 다른 함수를 호출하고이 함수의 호출자에게 직접 반환하도록합니다
- javascript - 업데이트 된 항목을 반환하지 않는 배열 맵 함수
- reactjs - 함수에 암시 적으로 반환 유형 '모든'오류가 있습니다
- android - Int를 반환하는 함수가 if 문의 일부가 될 수있는 방법은 무엇입니까?
- typescript - 선택적 매개 변수를 기반으로하는 함수 반환 유형
- laravel의 다른 함수에서보기로 돌아 가기
- javascript - 내 함수에서 무엇을 놓치고 있습니까 (오른쪽 요소보다 큰 요소 배열 반환)?
- javascript - 부울 값 배열 대신 부울 값 1 개를 반환하는 매핑 함수
- searchin 함수가 올바른 결과를 반환하지 않음
- python - 함수에서 eval () 및 return 결합
- c - 두 문자열을 연결하고 함수에서 반환 할 수 없습니다
- OpenCv의 폴더에서 여러 이미지 읽기 (python)
- 파이썬 셀레늄 모든 "href"속성 가져 오기
- html - 자바 스크립트 - 클릭 후 변경 버튼 텍스트 변경
- javascript - 현재 URL에서 특정 div 만 새로 고침/새로 고침
- JSP에 대한 클래스를 컴파일 할 수 없습니다
- git commit - 자식 - 로컬 커밋 된 파일에 대한 변경을 취소하는 방법
- jquery - JavaScript로 현재 세션 값을 얻으시겠습니까?
- JavaScript 변수를 HTML div에 '출력'하는 방법
- javascript - swiperjs에서 정지, 재생 버튼 추가
- python - 문자열에서 특정 문자 제거
오류 상태 코드로 인해 문제가 발생하면 대신 예외 사용을 고려해야합니다. 즉, 함수의 API를 변경하십시오
따라서 사후 조건으로 성공할 수 있습니다
적당한 Wyzwyz를 던져 실패한 경우이렇게하면 상태 코드를 검사하는 것을 "잊어 버릴"수 없습니다. 오류 조건을 처리하지 않으면 저수준 코드에서 발생한 예외가 자동으로 위로 올라갑니다. 당신은 단지
다음과 같은 저수준 예외std::exception
필요오류가 발생한 경우 수동 롤백 또는 할당 해제를 수행해야합니다. RAII는 실용적이지 않습니다. 이 경우, 당신은 expcetion을 다시 던질 것입니다.
던져진 중첩 예외를 사용하여 하위 수준 예외 메시지 또는 예외 유형을 고급 메시지로 변환하려고합니다.