c++ - 在 std::exception.what() 中使用 std::stringstream
问题描述
想要实现std::exception 类,尤其是what 函数,我遇到了std::stringstream 的问题。
简而言之,当我使用此实现时,它会打印一个空字符串:
const char *what() const throw () {
std::stringstream ss;
ss << "Error";
if (_line > -1)
ss << " at line " << std::to_string(_line);
ss << ": " << _msg;
return ss.str().c_str();
}
并在我使用此实现时打印一些东西(例如:“第 3 行错误”):
const char *what() const throw () {
std::stringstream ss;
ss << "Error";
if (_line > -1)
ss << " at line " << std::to_string(_line);
//ss << ": " << _msg; // COMMENT THIS LINE
return ss.str().c_str();
}
然后我什至尝试查看它是来自“:”还是来自变量 _msg (std::string) 但它们似乎都没有影响。
这是字符串流方面的缓冲区问题还是我方面的操作问题?如果这是一个操作问题,请解释我如何使用它。
解决方案
ss.str().c_str();
str()
做这个:
返回底层字符串的副本 [..]
所以你现在有一个临时std::string
的,你打电话c_str()
。这将返回一个指向由该临时管理std::string
的 (C) 字符串的指针。
因此,一旦此语句结束(在这种情况下,当函数返回时)临时std::string
将被破坏,这将删除/释放您从c_str()
指向的指针指向的内存。
所以你有一个无效的指针,访问它是未定义的行为。
解决方案:
制作 C 字符串的副本,然后将其返回。 不好,因为现在调用者必须释放这个副本,而这不是“API”的一部分
std::exception::what()
向您的类添加一个
std::string
成员,用(最好在类的构造函数中)的返回值填充它并返回该成员的内部 C 字符串:str()
struct my_exception : public std::exception { std::string description; my_exception() { std::stringstream ss; // code to fill ss description = ss.str(); } char const * what() const override { return description.c_str(); } };
保留核桃的重要评论:
不过,您需要小心。
std::string
复制时可能会抛出,如果发生这种情况,例如通过复制捕获的异常处理程序,std::terminate
将被调用并且程序将中止。另一方面,它可能只会在内存分配失败时抛出,这可能是一个您认为无论如何都无法恢复的错误(或不是)。
推荐阅读
- pandas - 熊猫数据框列的分组方式和计数
- gpu - LAPACKE 或 MAGMA GPU - 使用 Cholesky 分解的矩阵求逆 - 函数 magma_dpotrf_gpu 和 magma_dpotri_gpu
- nginx - 我可以使用 nginx 从我的 kubernetes 服务向主机发送请求吗
- sql - 如何在 RazorSQL 中编写参数化查询/脚本
- loops - 将迭代器与多个 URL 的抓取器结合使用,以避免冗长的重复脚本
- c - 带有 fgets 的 While cicle 中的分段错误:CSV 文件
- git - 使用 SSH 连接到 GitHub 到不在我帐户中的项目
- visual-studio - VS Code 中的 XML 文档注释?
- r - 使用 R CMD SHLIB 编译 F77 以在 R 包中使用。更改 `-fmax-stack-var-size=`
- java - 如何将使用来自多个信息类的属性的对象添加到主程序中的数组列表中?