2012-08-05 3 views
1

라이브러리를 만들고 있습니다. 고정 길이 문자열 클래스를 만들고 싶습니다.예외 예외 대 결과 코드 반환

#include <string> 
#include <iostream> 

#define OK 0 
#define TOO_LONG 1 
#define UNALLOWED_CHARACTERS 2 

struct MyString { 
    MyString(int l) 
     : m_length(l) { } 
    struct exception { 
     exception(int t, MyString *p) 
      : type(t), ptr(p) { } 
     int type; 
     MyString *ptr; 
    }; 
    int set(const std::string& name); 
    void set2(const std::string& name) throw(exception); 

    std::string m_str; 
    int m_length; 
}; 

int MyString::set(const std::string& s) 
{ 
    if(s.size() > 64) { 
     return TOO_LONG; 
    } else if(s.find('~') != std::string::npos) { 
     return UNALLOWED_CHARACTERS; 
    } else { 
     m_str = s; 
     return OK; 
    } 
} 

void MyString::set2(const std::string& s) throw(exception) 
{ 
    if(s.size() > m_length) { 
     throw exception(TOO_LONG, this); 
    } else if(s.find('~') != std::string::npos) { 
     throw exception(UNALLOWED_CHARACTERS, this); 
    } else { 
     m_str = s; 
    } 
} 

int main() 
{ 
    using namespace std; 
    //OPTION 1 
    { 
     MyString s1(10); 
     MyString s2(10); 
     int code; 

     code = s1.set("abcdefghijX"); 
     switch(code) { 
     case TOO_LONG: 
      //handle <-- 
      break; 
     case UNALLOWED_CHARACTERS: 
      //handle 
      break; 
     default: 
      //ok! 
      break; 
     } 

     code = s2.set("abcdefghi~"); 
     switch(code) { 
     case TOO_LONG: 
      //handle 
      break; 
     case UNALLOWED_CHARACTERS: 
      //handle <-- 
      break; 
     default: 
      //ok! 
      break; 
     } 
    } 

    //OPTION 2 
    { 
     MyString s1(10); 
     MyString s2(10); 
     try { 
      s1.set2("abcdefghijX"); 
      s2.set2("abcdefghi~"); 

     } catch(MyString::exception &e) { 
      cerr << "MyString::exception: "; 
      auto p = e.ptr; 
      if(p == &s1) cerr << "s1 "; 
      else if(p == &s2) cerr << "s2 "; 
      switch(e.type) { 
       case TOO_LONG: cerr << "too long"; break; 
       case UNALLOWED_CHARACTERS: cerr << "unallowed characters"; break; 
      } 
      cerr << endl; 
     } 

    } 
} 

어떤 버전의 MyString :: set()을 사용해야할지 모르겠다. 그러한 경우 국제 대회는 무엇입니까? 이 예제에서는 데모 용으로 STL을 사용했습니다.

+1

이것은 표면 상으로 큰 질문이지만 실제로 많은 논쟁을 이끌어 낼 것입니다. 그 종교적인 문제 중 하나입니다. – djechlin

+1

또한 throw 사양을 사용하지 마십시오. 내가 바꿀 수있는 것은 바보 같은 이유들이 런타임에 검사되어 std :: unexpected로 이어질 것이고 따라서 위반된다면 (디버그/개발 설정에서는 유용하지만 프로덕션 환경에서는 유용하지 않다.) 말 그대로 반대로 당신이 예외를 원한다. – djechlin

+1

@djechlin 좋은 지적. 또한 예외 사양은 C++ 11에서 사용되지 않습니다. – juanchopanza

답변

1

표준 라이브러리 함수의 동작을 모방하는 것이 좋습니다. BTW는 tr1 이후 고정 길이 문자열 클래스가 내장되어 있습니다. 무엇을하는지 보도록하겠습니다. 내가 편리한이 유일한 구현 예는 2010 년

 

std::tr1::array<int,5> arry; 
arry[10] = 42; // Oopsie. There is no element 10. 
 

컴파일하고 "디버그"버전으로 실행, 내가 어설 실패를 얻을 비주얼 C++입니다. "Release"를 위해 컴파일 될 때 공격적인 성명서는 조용히 않습니다. 그것은 바로 존재에서 최적화되었습니다. 좋아, 아마도 그게 항상 원하는 것은 아니 겠지. STL 또는 적어도 Microsoft의 구현을 모방하는 것에 대해 내가 말한 것을 잊어 버리십시오. 의식의 훈련이 계속됩니다 ...

프로그램이 범위 외 셀을 설정하려고하면 프로그램에서 논리 오류가 발생한다고 생각하는 것이 합리적이라고 생각합니다. 미션 크리티컬 소프트웨어에서 그런 상황에 대처하고 복구 할 수있는 코드를 마련하는 것은 좋은 생각 일 수 있습니다.

그래서 대답은 형식 std :: out_of_range 예외를 throw합니다.

그래서 있습니다.

+0

그래, 표준 예외에 대한 정보를 읽었을 뿐이며 내 요구에 적합합니다. mapname.name = "이 이름은 맵 이름에 비해 너무 길다." "('name'은 속성입니다.) 나는 단지 _std :: length_error_가 좀 더 정확하다고 생각합니다. – cubuspl42

1

일반적으로 C++에서는 예외를 사용하여 현재 컨텍스트에서 복구 할 수없는 오류를 나타내는 것이 좋습니다. 그러나 그것은 목적에 달려 있습니다. 예외없이 (효율성을 위해) 임베디드 환경에서 라이브러리를 컴파일하고 리턴 코드를 사용해야 할 수도 있습니다.

예외 코드를 사용하는 API로 쉽게 반환 할 수 있지만 그 반대는 아닙니다.

편집 :

는 예외 처리를 사용하지 의미가 있습니다 이유를 좀 더 추론 :

예외 처리는 일반적으로 필요에 대한 try/catch 블록이 호출 스택 + 약간의 성능에 배치 할 추가 정보를 소개합니다 이러한 정보를 만들고 확인하는 벌금.

은 참조 : 하나는 특별한 이유가없는까지를하지 않는 한 performance of C++0x exceptions

+0

오류가 "복구 불가능"이면 오류 코드가 필요 없거나 예외가 발생합니다. 펀트()에게 전화하고 그걸로 끝내라. –

+0

try-block은 "이 모든 작업이 끝나야 만합니다. 그렇지 않으면 스택을 풀어서 catch 블록으로 되돌려 보내야합니다." 보통 상태는 참으로 예외적입니다. 그러나 스택이 더 이상 필요하지 않은 프레임이있을 때 작업을 완료하는 것이 정상적인 프로그래밍의 수십 년 동안 정확하게 하나의 응용 프로그램을 기억합니다. 특별한 경우는 완료까지 달려 나가는 것이 었습니다 (그리고 나서 패배를 포기합니다). 이 함수의 경우 throw ("Success")가 원하는 결과이고 normal입니다. –

+0

@ JiveDadson 단어를 조금 변경했습니다.이 단어가 '복구 할 수 없음'을 의미하는 단어가 더 포괄적이라고 생각합니다. –