C ++ 예외 : std :: string 던지기
내 C ++ 메서드가 이상하고 복구 할 수없는 경우 예외를 throw하고 싶습니다. 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 ++ 표준 라이브러리의 기본 예외 클래스입니다. 문자열 자체는 사용 중에 예외를 throw 할 수 있으므로 예외 클래스로 사용하지 않는 것이 좋습니다. 그럴 경우 어디에 계십니까?
boost에는 예외 및 오류 처리에 대한 좋은 스타일에 대한 훌륭한 문서 가 있습니다. 읽을 가치가 있습니다.
몇 가지 원칙 :
std :: exception 기본 클래스가 있으면 예외가 파생되도록해야합니다. 그런 식으로 일반 예외 처리기는 여전히 몇 가지 정보를 가지고 있습니다.
포인터를 던지지 말고 객체를 던지십시오. 그런 식으로 메모리가 처리됩니다.
예:
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 ++ 컴파일러는 스택이 튀어 나와도 예외 데이터가 유지되도록 관리하므로 힙을 사용해야한다고 생각하지 마십시오.
Incidentally, throwing a std::string
isn't the best approach to begin with. You'll have a lot more flexibility down the road if you use a simple wrapper object. It may just encapsulate a string
for now, but maybe in future you will want to include other information, like some data which caused the exception or maybe a line number (very common, that). You don't want to change all of your exception handling in every spot in your code-base, so take the high road now and don't throw raw objects.
In addition to probably throwing something derived from std::exception you should throw anonymous temporaries and catch by reference:
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;
}
}
- You should throw anonymous temporaries so the compiler deals with the object lifetime of whatever you're throwing - if you throw something new-ed off the heap, someone else needs to free the thing.
- You should catch references to prevent object slicing
.
See Meyer's "Effective C++ - 3rd edition" for details or visit https://www.securecoding.cert.org/.../ERR02-A.+Throw+anonymous+temporaries+and+catch+by+reference
Simplest way to throw an Exception in 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;
}
This prints:
We caught a message: Cannot purturb at this time.
done
If you catch the thrown exception, the exception is contained and the program will ontinue. If you do not catch the exception, then the program exists and prints:
This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.
Though this question is rather old and has already been answered, I just want to add a note on how to do proper exception handling in C++11:
Use std::nested_exception
and std::throw_with_nested
Using these, in my opinion, leads to cleaner exception design and makes it unnecessary to create an exception class hierarchy.
Note that this enables you to get a backtrace on your exceptions inside your code without need for a debugger or cumbersome logging. It is described on StackOverflow here and here, how to write a proper exception handler which will rethrow nested exceptions.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace! You may also take a look at my MWE on GitHub, where a backtrace would look something like this:
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"
참고URL : https://stackoverflow.com/questions/134569/c-exception-throwing-stdstring
'Nice programing' 카테고리의 다른 글
Linux에서 Atom Editor를 업그레이드하는 방법은 무엇입니까? (0) | 2020.10.20 |
---|---|
Swift : 인덱스에서 문자열 배열 바꾸기 (0) | 2020.10.20 |
Objective C HTML 이스케이프 / 이스케이프 해제 (0) | 2020.10.20 |
식별 및 식별되지 않는 관계에 대해 여전히 혼란 스러움 (0) | 2020.10.20 |
C에서 단항 '+'연산자의 목적은 무엇입니까? (0) | 2020.10.20 |