2012-10-04 1 views
1

두 가지 다른 사용 모델을 가진 C++ 클래스를 작성했습니다. 하나는 외부로, 사용자가 예외를 발생 시키길 원하지 않는다고 가정합니다. 대신 오류 코드가 반환됩니다. 다른 사용법은 내부적인데, 지루한 오류 코드 검사를 피하려고 노력하며 예외 처리를 선호합니다.예외 및 오류 코드 기반 클래스 구현의 결합

두 방법을 결합하는 좋은 방법은 무엇입니까?

편집 :

  • 두 가지 접근법은 동일한 바이너리
  • 명시가 사용자에게 특별한 구조를 노출 암시
  • 피보다 더 사용할 수있다.
+0

'예외를 사용하지 않습니다.'라는 말은 (1) 언어 구성으로 허용되지 않습니다. RTTI가 비활성화되어 있거나 (2) 사용자가 코드에서 RTTI를보고 싶지 않은 경우? (2) 또한 "내부"코드에 영향을 미칩니다. – pmr

+0

(2). 맞습니다. public 멤버 함수 내에서 사용할 때 내부 코드는 항상 try-catch 블록 안에 있습니다. – Xyand

+0

글쎄, 만약 당신이 2 클래스와 외관과 함께 당신은 거기에 기본 유형과 파생 된 유형 사이에 절대 변환이 있는지 확인해야합니다. 반환 유형이 함께 사용할 수 없으므로 이러한 함수를 가상으로 만들 수는 없습니다. 나는 3 개의 클래스로 갈 것이다. 'throw '포인트가 함수의 중간에있을 수 있고 코드를 효율적으로 재사용 할 수 없기 때문에 이것은 여전히 ​​성가신 일이지만, 그것이 당신이 얻는 것입니다. – pmr

답변

1

오류 코드를 반환하는 클래스와 오류 코드를 반환하는 클래스의 두 가지 버전을 만듭니다. 둘 다 코드의 대부분을 포함하는 공통 기반에서 파생 될 수 있습니다.

+0

나는 그것에 대해 생각했다. 1.이 목적을 위해 3 가지 수업을 유지하는 것이 너무 번거롭지 않습니까? 나는 이런 종류의 치료가 필요한 여러 종류의 학급이 있습니다. 2. 두 가지 수업으로 충분하지 않습니까? 하나는 다른 하나의 외관으로 사용되며 예외를 오류 코드로 변환합니다. – Xyand

+0

@Albert, 그렇습니다. 두 클래스로 얻을 수 있습니다. 방금 3 명이 더 깨끗하다고 ​​생각했습니다. –

+0

@Albert 당신은 하나의 클래스만으로도 그것을 할 수 있고 각 함수의 두 가지 다른 버전을 제공 할 수 있습니다. 하나는 throw하고 하나는 그렇지 않습니다. 외장 프로그램이 때때로 객체를 다시 라이브러리에 전달하면 더 좋을 수도 있습니다. –

0

그런 일은 결코 시도하지 않았지만 여기에 내가 할 일이 있습니다.

오류 유형 :

extern const bool exceptionmode; 

enum error_codes {no_error, whatever}; 
struct error_type { 
    error_codes id; 
    //maybe also a non-owning const char* message? 

    error_type() :id(no_error) {} 
    error_type(error_codes code) :id(code) 
    { 
     if (exceptionmode) throw_as_exception(); 
    } 

    const char* get_as_string() { 
     switch(id) { 
     case whatever: return "out of bounds exception"; 
     case no_error: return "no error"; 
     default: return "unknown exception"; 
     } 
    } 
    void throw_as_exception() { 
     switch(id) { 
     case whatever: throw std::out_of_bounds("out of bounds exception"); 
     case no_error: break; //no error 
     default: throw std::exception("unknown exception"); 
     } 
    } 

}; 

클래스와 함수가 : 당신이 정말 용감한있어 경우 ERROR_TYPE 클래스는 주장 있도록 비교하거나 변환됩니다 않을 경우

class myclass { 
public:   
    error_type my_member_function() { 
     //stuff 
     if (condition) 
      return whatever; 
     //more stuff 
     return no_error; 
    } 
}; 

, 당신이 그것을 만들 수 있습니다 또는 아무도 반환 값을 확인하는 것을 잊어 버리지 않았는지 확인하기 위해 검사했습니다.

+0

'extern const bool exceptionmode;'가 너무 전역입니다. 두 가지 방법 모두 동일한 바이너리에서 사용할 수 있습니다. 그러나 클래스 생성자 (또는 템플릿 인수)에이 부울 인수를 제공하고 팩터 리 (또는 템플릿)를 사용하여 오류 코드를 생성 할 수 있습니다. 암시 적 캐스팅보다 명시적인 팩토리 메서드 호출을 선호합니다. 그것은 더 명확하고 사용자는 특별한 클래스를 알 필요가 없습니다. 열거 형 또는 정수. 이 접근 방식에 대해 내가 싫어하는 점은 예외 모드에서도 항상 결과를 반환한다는 것입니다. – Xyand

+0

좋아요, 물론 많은 옵션이 있습니다. 그리고 예, 항상 반환하지만 예외 모드에서는 항상 no_error를 반환하므로 무시할 수 있습니다. –

1

두 가지 클래스를 만드는 것이 다른 이유로 불가능하지 않으면 Mark Ransom의 대답이 내 것보다 낫습니다.

대신 인터페이스를 생성하여 모든 함수가 int * pRet = NULL과 같은 기본값을 가진 최종 인수를 갖도록 할 수 있습니다. 예외를 사용하는 것을 나타내는 pRet == NULL 인 경우 pRet! = NULL 인 경우, 호출자는 함수의 끝에서 오류 코드로 갱신되어야하는 포인터를 전달했습니다.

내부적으로 함수에서 예외를 catch 한 다음 pRet 인수에 따라 예외를 삼켜 서 다시 throw해야합니다.