C++异常-抛出c-string作为异常不好吗?

ktca8awb  于 2023-03-25  发布在  其他
关注(0)|答案(7)|浏览(112)

我正在编写一个小的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";
}
cgyqldqp

cgyqldqp1#

抛出一个标准的异常对象要好得多。一般来说,最好的做法是抛出从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;
    }
}
tcomlyy6

tcomlyy62#

抛出一个字符串字面量 * 通常是一个坏主意,因为随着代码的发展,程序员可能需要用一些更多的信息来丰富错误消息,例如变量的值,或者抛出异常的行号。
假设未知的客户端代码捕获了const char*,我们鼓励程序员使用一种更动态的机制来连接所需的信息:

  • a std::string+
  • a std::ostringstream
  • 一个字符缓冲区,可能还有strcat和/或sprintf()

最明显的使用这些的方法不起作用或不起作用:

// temporaries...
throw (std::string("couldn't parse input: ") + input).c_str();
throw (static_cast<std::ostringstream&&>(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/catch使用const char*仍然存在。
因此,使用一个嵌入了灵活的std::string描述 by value 的类对于编写可维护的代码非常重要。

zrfyljdw

zrfyljdw3#

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

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

第一个const是增加接收任何char阵列char*const char*char[]const char[]的能力
第二个const用于指定errorMessage不打算在catch块内更改

wydwbb8l

wydwbb8l4#

一般的问题是不能很容易地过滤你的异常,并根据类型对它们进行操作。然而,我不知道是否有一个C++特定的原因不这样做

qgzx9mmu

qgzx9mmu5#

std::exception(或者至少std::runtime_error)包含一个字符串,可以通过what()方法访问。你能做的最好的事情就是使用它,因为它是标准的,其他代码可以期望它,因为它无论如何都能满足你的目的。
在这种情况下最好坚持标准。

xzabzqsa

xzabzqsa6#

如果您将字符串作为错误抛出的想法是为了方便向用户显示错误,请考虑这将使本地化应用程序更加困难(可能会也可能不会引起您的关注)。
另外,如果应用程序的另一部分需要了解错误是什么,以便它可以对它做出React(例如,如果是断开连接错误,尝试自动重新连接,但如果是密码错误,只需向用户显示错误消息),最好有某种错误代码可用于异常捕获器。
在我们的应用程序中,我们的异常是从std::exception派生的。它们包含一个错误类型(枚举),一个调试错误消息(包括文件/行号)和一个本地化的错误字符串。

r8xiu3jd

r8xiu3jd7#

我觉得这个比较简单:)。

#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; 
}

相关问题