【问题标题】:How to properly create a custom exception with a message?如何正确创建带有消息的自定义异常?
【发布时间】:2014-09-10 05:24:58
【问题描述】:

我是 C++ 新手,我正在尝试创建一个自定义异常,该异常在其 ctor 中接收一条消息。

我现在拥有的是这样的:

class LevelLoadException : public std::exception
{
public:
    LevelLoadException(std::string msg) : m_message(msg) { }
    const char * what () const throw ()
    {
        return m_message.c_str();
    }
private:
    std::string m_message;
};

在我的调用代码中,我将此作为 switch 语句的一部分(c 是一个字符,或者更具体地说,c = line[x]; 其中x 是一个intline 是一个std::string );

default:
    throw LevelLoadException("Invalid Character in Level: " + c);

问题是我的异常得到了一个完全不相关的字符串(这是抛出的同一方法的一部分:throw std::exception("There is more than 1 player start in the level."))。

我已经排除了一个逻辑错误——我的程序到达了抛出带有正确字符串的正确异常的行。所以我很确定这是一个生命周期/内存管理问题。

据我了解,C++ 默认是按值复制的。所以我认为调用LevelLoadException 的ctor 会立即复制字符串。但似乎有一些指针的东西正在发生,因为我正在构建的字符串看起来像一个 C 字符串 (const char*)。

我查看了 std::exception 类,它以 const char* const& 作为消息,然后在后台执行了一些类似 C 的 strcopy/malloc(MSVC / Visual Studio 2012 Update 4)。

我不是百分百确定我真正需要什么。我想我想要的是一个内置在调用者中的字符串,然后移动/复制到异常中(它现在拥有仅由异常拥有的字符串的副本),然后调用者中的那个在它退出时被销毁范围。

谁能给我a pointer 我应该做些什么不同的事情才能正确地做到这一点?

【问题讨论】:

  • 你发现了一个标准异常?
  • @Christophe 不,我在消费者中有catch(LevelLoadException& e)
  • 您应该派生自 std::runtime_error 而不是 std::exception。然后你的班级可以减少到couple of lines
  • 如果你决定不走std::runtime_error路线,你应该考虑做按需格式化,因为在创建那些std::strings的过程中分配错误会导致麻烦。

标签: c++ exception c++11


【解决方案1】:

"Invalid Character in Level: " + c 不会做你认为的那样。它的意思是“一个char* 指针,它从字符串文字的开头偏移了N 个字节”,其中N 是存储在c 中的字符的ASCII 码。文字实际上比N 字符短的可能性很高,在这种情况下,该程序包含缓冲区溢出并表现出未定义的行为。

做起来

throw LevelLoadException(std::string("Invalid Character in Level: ") + c);

【讨论】:

  • 啊,谢谢。所以"string" 返回一个char *(对于C 向后兼容)然后我正在做指针数学(char c 变成数值99)?将"string" 转换为C++ 字符串使用operator+std::string?
  • @Praetorian:啊,对。我会进行更正,尽管它不会从根本上改变答案。
  • @MichaelStum:你明白了(模 99 实际上是恰好存储在变量 c 中的任何字符的 ASCII 码;这是我的错误,很抱歉造成混淆)。跨度>
  • 所以很幸运,我得到了一些其他有效的字符串,而不是垃圾或访问冲突:)(好吧,可能运气不好,因为访问冲突会更清楚)。谢谢,现在可以使用了!
  • @MichaelStum:编译器通常将所有常量静态数据集中到程序生成的二进制文件的同一块中 - 并且通常更喜欢将所有字符串集中在一起 - 所以当你做怪事时,你可以很容易地看到你描述的行为字符串文字地址的东西。
猜你喜欢
  • 2014-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-04
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 2021-03-17
相关资源
最近更新 更多