2011-02-10 2 views
4

나는 몇 가지 방법이 좋아하는이 클래스는 다음이 (더) :RAII를 사용하여 캐치를 시도 하시겠습니까?

Logpp& operator<<(std::ostream& (*manip)(std::ostream&)) 
    { 
     try 
     { 
      *p_Stream << manip; 
      return *this; 
     } 
     catch(ios_base::failure& e) 
     { 
      //MyException has a stringstream inside and can use operator<< 
      throw MyException("IO failure writing to log file : ") << e.what() << endl; 
     } 
    } 

Q1 :

template<class T> 
    Logpp& operator<<(T const& obj) 
    { 
     *p_Stream << obj ; 
     return *this ; 
    } 

    Logpp& operator<<(char const* zString) 
    { 
     *p_Stream << zString ; 
     return *this ; 
    } 

    Logpp& operator<<(std::ostream& (*manip)(std::ostream&)) 
    { 
     *p_Stream << manip; 
     return *this ; 
    } 

내가 형태의 시도의 catch 블록에서 함수의 몸을 둘러싸하려면 : 이런 예외를 사용하는 것이 좋습니다? (각 기능에서). 나는 익숙하지 않아 예외를 사용하므로 잘 모르겠습니다.

질문 2 : Q1에 대한 답변이 양수이면 중복을 제거하기 위해 이와 같은 조치를 취할 수 있습니까?

Logpp& operator<<(std::ostream& (*manip)(std::ostream&)) 
    { 
     Catch<ios_base::failure> tc(); 
     try 
     { 
      *p_Stream << manip; 
      return *this; 
     } 
     //destructor of tc will be written to catch the template exception type and rethrow as a MyException. 
    } 
+0

나는 파일과 라인 정보를 삽입하는 매크로와 비슷한 일을한다. 매크로도 사용할 수 있습니까? – Anycorn

+0

왜 템플릿 기능과 동일한 템플릿 외 과부하가 있습니까? 그것들은 모두 인라인 (inline)이기 때문에 비언어적 인 것으로 논쟁을 가져가는 것이 중요하지 않습니다. – MSalters

답변

6

Q1 :이 같은 예외를 사용하는 것이 좋습니다? (각 기능에서). 나는 익숙하지 않아 예외를 사용하므로 잘 모르겠습니다.

예외 정보를 풍부하게하고 특정 ios_base :: failure 함수를 다른 것과 구별하지 않는 한 특별히 문제는 없습니다. 각 함수를 더 크게/더 복잡하게 만들고 싶습니다. 그것이 다른 것을 작게/더 단순하게 만들면.

질문 2 : Q1에 대한 답변이 양수이면 중복을 제거하기 위해 이와 같은 조치를 취할 수 있습니까?

잠재적으로 매크로를 사용하여 try/catch 블록을 생성 할 수 있습니다. 당신이 제안한 것을한다면, 예외가 처리되는 동안 소멸자가 호출 될 것입니다 : 다시 던지려고하면 terminate()이 호출됩니다. Q2에 ... MEH

답변 : Q1에 http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9

3

답변 : 자세한 내용은 C++ 라이트 FAQ를 확인 아니, 소멸자의 몸은 항상 실행되며 예외 데이터를 수신하지 않습니다. 이런 식으로 catch 절을 바꿀 수는 없습니다.

가능하다해도 RAII라는 용어에 해당하지 않습니다. 자동 메모리 규칙을 사용하면 특정 일이 일어나도록하는 데 사용된다는 점에서 RAII와 유사하지만, 그 점이 다릅니다. 어디가되고있는 (R) esource (A)는 ... 예를 들어, quired 것

3

광고 Q1 : 나는 약간에 대해 권하고 싶습니다

. 예외를 처리하는 호출자가 내부 세부 사항을 알지 못하고 원래 예외가 이해가 안되는 경우 예외를 처리해야합니다. 하지만 operator<<을 던지려면 std::ios_base::failure이 완벽한 감각을 발휘하여 여기를 감쌀 것입니다.

광고 Q2 :

아니,하지만 당신은 같은 것을 할 수있는 :

return wrap_exception(bind(&Logpp::do_output, this, manip)); 
0

포장 예외로 TR1/부스트에서

Logpp& do_output(std::ostream& (*manip)(std::ostream&)) 
{ 
    *p_Stream << manip; 
    return *this; 
} 

Logpp& operator<<(std::ostream& (*manip)(std::ostream&)) 
{ 
    return wrap_exception(&Logpp::do_output, this, manip); 
} 

(아마 좀 더 쉽게 사용하는 바인드 인 필요한 경우에만해야하는 일종의 - 일반적으로 유용하지는 않습니다.

당신은 소멸자에서 예외를 잡을 수는 없지만, 다음과 같은 작업을 수행 할 수 있습니다 그것은 가치가되지 않을 수도 있습니다

void handleCurrentException() 
{ 
    try { throw; } // rethrow currently active exception 
    catch (ios_base::failure& e) 
    { 
    // exception handling/rethrowing code 
    } 
} 

Logpp& operator<<(std::ostream& (*manip)(std::ostream&)) 
{ 
    try 
    { 
    *p_Stream << manip; 
    return *this; 
    } 
    catch(...) 
    { 
    handleCurrentException(); 
    } 
} 

다음은 rethrowing 코드가 짧습니다. 예외 처리 코드가 길면 유용 할 수 있습니다.

관련 문제