C ++异常 - 将c-string作为异常抛出错误?

时间:2011-06-06 06:18:50

标签: c++ exception

我正在研究一个小型的c ++程序并学习异常。以下代码是“坏”,如果是,我该怎么做才能改进它?

try {
    // code
    if (some error) {
        throw "Description of error.";
    }
}
catch (char* errorMessage) {
    cerr << errorMessage << endl << "Fatal error";
}

char数组作为例外抛出是否有任何问题?

编辑: 这会是一个更好的方法吗?

const char errorMessage[] = "Description of error";

try {
    // code
    if (some error) {
        throw errorMessage;
    }
}
catch (char* errorMessage) {
   cerr << errorMessage << endl << "Fatal error";
}

7 个答案:

答案 0 :(得分:48)

抛出标准异常对象要好得多。一般来说,最好的做法是抛出从std::exception派生的东西,这样如果在某些情况下它会导致程序终止,那么实现更有可能打印出有用的诊断。

因为不难做到这一点,我绝不会建议抛出原始字符串文字。

#include <stdexcept>

void someFunction()
{
    try {
        // code
        if (some error) {
            throw std::runtime_error( "Description of error." );
        }
    }
    catch (const std::exception& ex) {
        std::cerr << ex.what() << "\nFatal error" << std::endl;
    }
}

答案 1 :(得分:10)

抛出字符串文字 通常是一个坏主意,因为随着代码的发展,程序员可能需要使用更多信息来丰富错误消息,例如:变量的值,或抛出异常的行号。

鉴于未知的客户端代码正在捕获const char*,程序员鼓励使用更动态的机制来连接所需的信息:

  • 一个std::string+
  • a std::ostringstream
  • 一个char缓冲区,可能是strcat和/或sprintf()

最明显的使用方式不起作用或效果不佳:

// temporaries...
throw (std::string("couldn't parse input: ") + input).c_str();
throw (std::ostringstream() << "error line " << __LINE__).str().c_str();
char buf[1024]; sprintf(buf, "error line %ld%", __LINE); throw buf;

// not thread-safe
static char buf...

即使程序员知道不执行任何这些操作,他们仍然可以正确地找到需要开始接受更丰富的值类型的所有客户端代码,尤其是在其他throw / {{1 } catch的使用仍然存在。

因此,使用按值嵌入灵活const char*描述的类对于编写可维护代码非常重要。

答案 2 :(得分:5)

抛出char数组没有问题。只是你应该收到,

catch(const char* const errorMessage) {...}

第一个const是添加接收任何char数组的能力char* const char* char[] const char[]

第二个const用于指定errorMessage块内的catch无意更改

答案 3 :(得分:1)

一般问题是无法轻松过滤您的例外情况并根据类型对其采取行动。但是,我不知道是否有C ++特定原因不这样做

答案 4 :(得分:1)

std :: exception(或者至少是std :: runtime_error)包含一个字符串,可以通过what()方法访问。你可以做的最好的事情是使用它,因为它是标准的,而其他代码可以期待它,因为它无论如何都符合你的目的。

在这种情况下,最好坚持标准。

答案 5 :(得分:0)

如果您将字符串作为错误抛出的想法是为了方便向用户显示错误,请考虑这会使您的应用程序本地化更加困难(尽管可能会或可能不会引起您的关注)。

此外,如果应用程序的另一部分需要了解错误是什么,那么它可以对它做出反应(例如,如果它是断开连接错误,请尝试自动重新连接,但如果是密码错误,则只显示错误消息用户),最好为异常捕获器提供某种错误代码。

在我们的应用程序中,我们的异常派生自std :: exception。它们包含错误类型(枚举),调试错误消息(包括文件/行号)和本地化错误字符串。

答案 6 :(得分:0)

我认为这要简单得多。 :)。

#include <iostream>
#include <exception>

using namespace std;

int main() {
    try {
        throw runtime_error("This is an Error"); 
    }catch (exception& e){
        cout << "Exception: " << e.what() << endl; 
    }
    return 0; 
}