문제

C ++ 메소드가 이상한 것을 만나고 회복 할 수 없을 때 예외를 던지고 싶습니다. 던져도 괜찮습니까? std::string 바늘?

내가 기대했던 일은 다음과 같습니다.

void Foo::Bar() {
    if(!QueryPerformanceTimer(&m_baz)) {
        throw new std::string("it's the end of the world!");
    }
}

void Foo::Caller() {
    try {
        this->Bar(); // should throw
    }
    catch(std::string *caught) { // not quite sure the syntax is OK here...
        std::cout << "Got " << caught << std::endl;
    }
}
도움이 되었습니까?

해결책

예. std::exception C ++ 표준 라이브러리의 기본 예외 클래스입니다. 문자열을 사용하는 동안 예외를 던질 수 있기 때문에 문자열을 예외 클래스로 사용하지 않을 수 있습니다. 그런 일이 발생하면 어디에 있을까요?

부스트는 훌륭합니다 문서 예외와 오류 처리를위한 좋은 스타일. 읽을 가치가 있습니다.

다른 팁

몇 가지 원칙 :

  1. STD :: 예외 기본 클래스가 있으므로 예외가 가져와야합니다. 이렇게하면 일반적인 예외 핸들러에는 여전히 정보가 여전히 있습니다.

  2. 포인터를 던지지 말고 객체, 그런 식으로 메모리가 처리됩니다.

예시:

struct MyException : public std::exception
{
   std::string s;
   MyException(std::string ss) : s(ss) {}
   ~MyException() throw () {} // Updated
   const char* what() const throw() { return s.c_str(); }
};

그런 다음 코드에서 사용하십시오.

void Foo::Bar(){
  if(!QueryPerformanceTimer(&m_baz)){
    throw MyException("it's the end of the world!");
  }
}

void Foo::Caller(){
  try{
    this->Bar();// should throw
  }catch(MyException& caught){
    std::cout<<"Got "<<caught.what()<<std::endl;
  }
}

이 모든 작업 :

#include <iostream>
using namespace std;

//Good, because manual memory management isn't needed and this uses
//less heap memory (or no heap memory) so this is safer if
//used in a low memory situation
void f() { throw string("foo"); }

//Valid, but avoid manual memory management if there's no reason to use it
void g() { throw new string("foo"); }

//Best.  Just a pointer to a string literal, so no allocation is needed,
//saving on cleanup, and removing a chance for an allocation to fail.
void h() { throw "foo"; }

int main() {
  try { f(); } catch (string s) { cout << s << endl; }
  try { g(); } catch (string* s) { cout << *s << endl; delete s; }
  try { h(); } catch (const char* s) { cout << s << endl; }
  return 0;
}

당신은 h에서 f ~ g를 선호해야합니다. 가장 바람직하지 않은 옵션에서는 메모리를 명시 적으로 제거해야합니다.

그것은 효과가 있지만 내가 당신이라면 그렇게하지 않을 것입니다. 완료시 힙 데이터를 삭제하지 않는 것 같습니다. 즉, 메모리 누출을 만들었습니다. C ++ 컴파일러는 스택이 팝업 되더라도 예외 데이터가 살아남을 수 있도록 관리하므로 힙을 사용해야한다고 생각하지 마십시오.

덧붙여서, 던지는 a std::string 시작하기 가장 좋은 접근법은 아닙니다. 간단한 래퍼 객체를 사용하면 도로 아래로 훨씬 더 유연성이 있습니다. 단지 캡슐화 할 수 있습니다 string 지금은 예외를 일으킨 일부 데이터와 같은 다른 정보를 포함시키고 싶을 것입니다 (매우 일반적). 코드 기반의 모든 지점에서 예외 처리를 변경하고 싶지 않으므로 지금 높은 도로를 타고 생체 물체를 던지지 마십시오.

STD :: 예외에서 파생 된 것을 던질뿐만 아니라 익명의 임시를 던지고 참조로 잡아야합니다.

void Foo::Bar(){
  if(!QueryPerformanceTimer(&m_baz)){
    throw std::string("it's the end of the world!");
  }
}

void Foo:Caller(){
  try{
    this->Bar();// should throw
  }catch(std::string& caught){ // not quite sure the syntax is ok here...
    std::cout<<"Got "<<caught<<std::endl;
  }
}
  • 컴파일러가 당신이 던지는 모든 것의 객체 수명을 다루도록 익명의 임시를 던져야합니다.
  • 물체 슬라이싱을 방지하기 위해 참조를 포착해야합니다

.

자세한 내용 또는 방문은 Meyer의 "Effective C ++ -3rd Edition"을 참조하십시오. https://www.securecoding.cert.org/.../err02-a.+ throw+ anonymous+tempories+및 catch+by+ reference

C ++에서 예외를 던지는 가장 간단한 방법 :

#include <iostream>
using namespace std;
void purturb(){
    throw "Cannot purturb at this time.";
}
int main() {
    try{
        purturb();
    }
    catch(const char* msg){
        cout << "We caught a message: " << msg << endl;
    }
    cout << "done";
    return 0;
}

이 인쇄물 :

We caught a message: Cannot purturb at this time.
done

던져진 예외를 포착하면 예외가 포함되어 있으며 프로그램이 온화됩니다. 예외를 포착하지 않으면 프로그램이 존재하고 인쇄합니다.

This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.

이 질문은 다소 오래되었고 이미 답변되었지만 적절한 예외 처리 방법에 대한 메모를 추가하고 싶습니다. C ++ 11:

사용 std::nested_exception 그리고 std::throw_with_nested

제 생각에 이것들을 사용하면 더 깨끗한 예외 설계로 이어지고 예외 클래스 계층 구조를 만들 필요가 없습니다.

이것은 당신을 가능하게합니다 예외를 제외하고 배경으로 받으십시오 디버거 또는 성가신 로깅이 필요없는 코드 내부. stackoverflow에 설명되어 있습니다 여기 그리고 여기, 중첩 된 예외를 재고하는 적절한 예외 핸들러를 작성하는 방법.

파생 된 예외 클래스 로이 작업을 수행 할 수 있으므로 그러한 배경계에 많은 정보를 추가 할 수 있습니다! 당신은 또한 내 것을 볼 수도 있습니다 Github에 MWE, 배경계가 다음과 같이 보일 수있는 곳.

Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top