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

Tim*_*Tim 34 c++ exception

我正在研究一个小型的c ++程序并学习异常.以下代码是"坏",如果是,我可以做些什么来改进它?

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

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

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

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

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

CB *_*ley 49

抛出标准异常对象要好得多.一般来说,最佳做法是抛出一些派生的东西,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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @GeneBushuyev:这是一个潜在的问题,但如果这样的最小分配失败,你通常会以非常糟糕的方式.如果我的情况不仅仅是理论上的问题,我可能仍会使用从`std :: exception`派生的真正的异常对象,它的重载`what()`返回了一个指向文字字符串的指针.总是必须分配异常对象的空间(即使只有一个指针),并且只要抛出异常就初始化异常对象. (2认同)
  • @Tim:`std::runtime_error` 存储构造它的字符串。通常(但不一定),这将涉及动态分配的内存。文字字符串具有静态存储持续时间。如果您抛出指向具有自动存储持续时间的对象(例如“堆栈上”的`char` 数组)的对象,并且该对象不在异常处理程序的范围内,那么您将遇到严重的潜在错误。 (2认同)

Ton*_*roy 10

投掷一个字符串字面量一般一个坏主意,因为,随着代码的改进,程序员可能需要一些更多的信息,从而丰富错误信息,如变量的值,或从中抛出异常的行号.

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

  • 一个std::string+
  • 一个 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...
Run Code Online (Sandbox Code Playgroud)

即使程序员知道不执行任何这些操作,他们仍然可以正确地找到需要开始接受更丰富的值类型的所有客户端代码,特别是如果其他throw/ catch使用const char*持续存在的话.

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


iam*_*ind 5

投掷char数组没有问题.只是你应该收到,

catch(const char* const errorMessage) {...}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 第二个`const`是打算,`errorMessage`不应该改变. (2认同)
  • 这是完全合法的,但不是最佳做法.见查尔斯的回答. (2认同)