C++ 从std::exception';返回动态字符串;什么`
此时,我确信我应该创建C++ 从std::exception';返回动态字符串;什么`,c++,exception,constants,C++,Exception,Constants,此时,我确信我应该创建std::exception的子类来满足所有异常抛出需求。现在我在看如何覆盖what方法 我所面临的情况是,如果字符串what返回的是动态的,那么它将非常方便。例如,一些代码解析XML文件,在错误消息中添加位置或行号对我很有用 我正试着跟着这条路走 我想知道的是: what返回一个const char*,这意味着任何捕手都不可能释放字符串。所以我需要其他地方来存储结果,但那会在哪里呢?(我需要线程安全。) what在其签名中还包括throw()。虽然我可以防止我的what
std::exception
的子类来满足所有异常抛出需求。现在我在看如何覆盖what
方法
我所面临的情况是,如果字符串what
返回的是动态的,那么它将非常方便。例如,一些代码解析XML文件,在错误消息中添加位置或行号对我很有用
我正试着跟着这条路走
我想知道的是:
返回一个what
,这意味着任何捕手都不可能释放字符串。所以我需要其他地方来存储结果,但那会在哪里呢?(我需要线程安全。)const char*
在其签名中还包括what
。虽然我可以防止我的throw()
抛出任何东西,但在我看来,这种方法实际上并不适用于任何过于动态的东西。如果what
不是正确的位置,那么我应该在哪里执行此操作what
从目前为止我得到的答案来看,实现这一点的唯一方法似乎是将字符串存储在异常中。Boost指南建议不要这样做,这让我很困惑,因为
std::runtime\u error
就是这样做的
即使我使用C字符串,我也必须使用静态大小的缓冲区,或者进行内存管理,这也可能会失败。(我想知道这是否是std::string
的复制构造函数中唯一可能出错的地方。这意味着使用动态分配的C-string不会获得任何好处。)
还有其他选项吗?好吧,没问题,您可以简单地实现派生异常类的构造函数,以格式化将从what()返回的字符串。在析构函数中释放用于该函数的缓冲区。我的异常类通常只有构造函数,请看以下几行:
class MyEx: public std::runtime_error
{
public:
MyEx(const std::string& msg, int line):
std::runtime_error(msg + " on line " + boost::lexical_cast<string>(line))
{}
};
然而,关于boost的指导原则,也许您应该注意一点,数字数据(位置和线条)最好通过其他方法以数字的形式提供。指导方针说,不要太担心
what()
消息。Boost的指导方针似乎基于两个假设:复制异常对象可能引发另一个异常,而what()字符串不是一个健壮或可靠的工具。如果您正在编写一个可以在各种环境中广泛使用的库,那么这些都是值得关注的问题。如果您对如何使用异常有更好的了解,那么您可以判断这些关注是合理的还是无事生非。编程都是关于一系列的权衡,而对于Boost开发人员来说,有意义的权衡可能不适用于你。 < P>我接受UncleBens的回答,因为我认为这是对我原来问题的最正确和最完整的回答。
作为参考,我实际上选择了一个不同的解决方案,并完全停止使用what
。我已经对代码进行了重构,现在我必须使用类似这样的内容作为基本异常类:
struct Exception : public virtual std::exception
{
virtual const char* what() const throw()
{
try {
return typeid(this).name();
}
catch (const std::exception& e) {
return "<unknown exception>";
}
}
// Extended description; may throw.
virtual void describe(std::ostream& out) const = 0;
};
结构异常:公共虚拟std::异常
{
虚拟常量char*what()常量throw()
{
试一试{
返回typeid(this.name();
}
捕获(const std::exception&e){
返回“”;
}
}
//扩展描述;可能抛出。
虚拟空描述(标准::ostream&out)常数=0;
};
基本上就是用我能找到的最有意义的东西来填充
什么
,而不用在其他地方费心。我想,我要看看这是怎么回事。这似乎与gf的答案相似,还是说普通的C字串?因为运行时将异常作为一个值传递,所以不可能在捕获之前释放字符串吗?我不确定是否会释放哪个字符串?您必须在存储指针的异常类中实现复制构造函数。添加了Boost引导线点,如果不适合您,请重新编辑。更令人担忧的是,我发现std::runtime\u error
存储字符串。因此,标准库本身与Boost指南相矛盾?Boost作者担心字符串的格式化或复制会引发(内存不足?)错误的可能性。异常对象总是在抛出时进行复制。
struct Exception : public virtual std::exception
{
virtual const char* what() const throw()
{
try {
return typeid(this).name();
}
catch (const std::exception& e) {
return "<unknown exception>";
}
}
// Extended description; may throw.
virtual void describe(std::ostream& out) const = 0;
};