当前位置:  开发笔记 > 编程语言 > 正文

c ++异常:抛出std :: string

如何解决《c++异常:抛出std::string》经验,为你挑选了5个好方法。

当我的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;
    }
}

christopher_.. 97

是.std::exception是C++标准库中的基本异常类.您可能希望避免将字符串用作异常类,因为它们本身可以在使用期间抛出异常.如果发生这种情况,那么你将在哪里?

boost有关于异常和错误处理的良好风格的优秀文档.值得一读.



1> christopher_..:

是.std::exception是C++标准库中的基本异常类.您可能希望避免将字符串用作异常类,因为它们本身可以在使用期间抛出异常.如果发生这种情况,那么你将在哪里?

boost有关于异常和错误处理的良好风格的优秀文档.值得一读.


旁注:如果异常对象本身抛出,将调用std :: terminate,这就是你要去的地方(而且它不漂亮!)
请参阅http://www.gotw.ca/publications/mill16.htm,了解一个关于为什么要浪费分配抛出异常的论点是浪费时间.另一个论点是这个答案是std :: runtime_exception和family一起做的,所以为什么不呢?

2> PierreBdR..:

一些原则:

    你有一个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 "<


从std :: runtime_exception派生是不是更好?

3> 小智..:

所有这些工作:

#include 
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.请注意,在最不优选的选项中,您需要明确释放内存.



4> Daniel Spiew..:

它有效,但如果我是你,我不会这样做.完成后,您似乎没有删除该堆数据,这意味着您已经创建了内存泄漏.C++编译器负责确保即使在弹出堆栈时异常数据也保持活动状态,因此不要觉得您需要使用堆.

顺便说一句,抛出a std::string并不是最好的方法.如果你使用一个简单的包装器对象,你将会有更多的灵活性.它现在可能只是封装一个string,但也许将来你可能想要包含其他信息,比如导致异常的一些数据或者行号(非常常见).您不希望在代码库中的每个位置更改所有异常处理,因此请立即采取行动,不要抛出原始对象.



5> Michael Burr..:

除了可能抛出从std :: exception派生的东西之外,你应该抛出匿名临时值并通过引用捕获:

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 "<

你应该抛出一个匿名临时代码,这样编译器就会处理你扔掉的任何东西的对象生命周期 - 如果你从堆中抛出一些新的东西,别人需要释放它.

您应该捕获引用以防止对象切片

.

有关详细信息,请参阅Meyer的"Effective C++ - 3rd edition"或访问https://www.securecoding.cert.org/.../ERR02-A.+Throw+anonymous+temporaries+and+catch+by+reference

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有