C++重写what()函数无输出问题:代码故障排查
问题排查:
what()无输出的原因与修复方案 核心问题
你代码里的what()方法返回的是悬空指针,导致访问时出现未定义行为(表现为无输出):
- 在
Interval_OutOfRange的what()中,ss.str()会生成一个临时std::string对象,调用c_str()获取的指针指向该临时对象的内部字符数组。 - 当
return语句执行完毕,这个临时对象会被立即销毁,返回的指针就变成了无效的悬空指针,后续访问它自然无法得到正确输出。
另外原代码还有一个逻辑问题:Interval构造函数不管传入值是否在范围内都会抛出异常,这不符合Interval类的设计意图。
修复方案
方案1:存储持久化的错误字符串
修改异常类,将构造时生成的错误字符串存储为类成员,避免临时对象销毁导致的指针失效:
#include <iostream> #include <stdexcept> #include <string> #include <sstream> class Interval_OutOfRange : public std::out_of_range { private: std::string error_msg; // 持久存储错误信息 public: Interval_OutOfRange(int min, int max, int value) : std::out_of_range{"interval value out of range"} { std::stringstream ss; ss << value << " is not inside interval [" << min << ", " << max << "]"; error_msg = ss.str(); } char const * what() const noexcept override { return error_msg.c_str(); // 返回有效指针 } }; template<int Min, int Max> class Interval { public: Interval(int value) : value_{value} { // 补充范围判断,仅当值越界时抛异常 if (value < Min || value > Max) { throw Interval_OutOfRange{Min, Max, value}; } } auto get() const { return value_; } auto set(int value) { if (value < Min || value > Max) { throw Interval_OutOfRange{Min, Max, value}; } value_ = value; } private: int value_; }; int main() { try { Interval<7, 17> obj(19); } catch (Interval_OutOfRange& ex) { std::cout << ex.what() << std::endl; } }
方案2:利用基类存储错误信息(更简洁)
直接将自定义错误字符串传递给std::out_of_range基类的构造函数,无需重写what(),由基类负责管理字符串存储:
#include <iostream> #include <stdexcept> #include <string> #include <sstream> class Interval_OutOfRange : public std::out_of_range { public: Interval_OutOfRange(int min, int max, int value) // 使用lambda生成错误字符串并传递给基类 : std::out_of_range([&](){ std::stringstream ss; ss << value << " is not inside interval [" << min << ", " << max << "]"; return ss.str(); }()) {} }; template<int Min, int Max> class Interval { public: Interval(int value) : value_{value} { if (value < Min || value > Max) { throw Interval_OutOfRange{Min, Max, value}; } } auto get() const { return value_; } auto set(int value) { if (value < Min || value > Max) { throw Interval_OutOfRange{Min, Max, value}; } value_ = value; } private: int value_; }; int main() { try { Interval<7, 17> obj(19); } catch (Interval_OutOfRange& ex) { std::cout << ex.what() << std::endl; } }
内容的提问来源于stack exchange,提问作者Simon Rechermann
相关产品推荐
相关产品推荐

