繁体   English   中英

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

[英]C++ Exceptions - Is throwing c-string as an exception bad?

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

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

char数组作为异常抛出有什么问题吗?

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

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

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

最好抛出一个标准异常 object。 一般来说,最好的做法是抛出一些从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;
    }
}

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

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

  • 一个std::string+
  • 一个std::ostringstream
  • 一个字符缓冲区,也许还有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...

即使程序员知道不做任何这些,他们仍然有合适的时间找到所有需要开始接受更丰富的值类型的客户端代码,尤其是在const char*的其他throw / catch用法持续存在的情况下。

因此,使用 class按值嵌入灵活的std::string描述对于编写可维护的代码非常重要。

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

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

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

第二个const是指定errorMessage不打算在catch块内更改

存在无法轻松过滤异常并根据类型对其进行操作的普遍问题。 但是,我不知道是否有 C++ 具体原因不这样做

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM