Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从std::exception';返回动态字符串;什么`_C++_Exception_Constants - Fatal编程技术网

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