C++98自定义std::exception的what()仅输出父类信息,如何解决?
C++98中自定义异常基类捕获无法获取自定义消息的解决办法
问题根源
你碰到的情况是因为自定义异常类的what()方法没有正确重写std::exception的虚函数。C++98里std::exception的what()签名是virtual const char* what() const throw();,如果你的子类方法签名不匹配(比如缺了const、throw(),或者返回值类型不对),编译器会把它当成一个新函数,而非重写,导致调用基类的默认实现。另外,如果你用catch(const std::exception e)值捕获,会触发对象切割,直接丢失子类的所有信息,必须用引用捕获const std::exception&。
正确的自定义异常实现
按以下方式编写MyCustomException,确保多态正常工作:
#include <exception> #include <cstring> class MyCustomException : public std::exception { private: char* m_message; public: explicit MyCustomException(const char* msg) { // C++98中手动分配内存存储消息 m_message = new char[strlen(msg) + 1]; strcpy(m_message, msg); } // C++98需要手动实现拷贝构造和赋值运算符,避免内存泄漏 MyCustomException(const MyCustomException& other) { m_message = new char[strlen(other.m_message) + 1]; strcpy(m_message, other.m_message); } MyCustomException& operator=(const MyCustomException& other) { if (this != &other) { delete[] m_message; m_message = new char[strlen(other.m_message) + 1]; strcpy(m_message, other.m_message); } return *this; } ~MyCustomException() throw() { delete[] m_message; } // 严格匹配基类虚函数签名,确保多态生效 const char* what() const throw() { return m_message; } };
测试代码
用基类引用捕获即可正确获取自定义消息:
#include <iostream> int main() { try { throw MyCustomException("这是我的自定义异常消息"); } catch (const std::exception& e) { std::cout << e.what() << std::endl; // 输出自定义消息 } return 0; }
注意事项
- 必须使用
catch(const std::exception& e)引用捕获,绝对不能用值捕获,否则会切割对象。 - 子类
what()方法的签名必须和基类完全一致,包括const修饰和throw()异常说明符,C++98中这部分是重写的必要条件。 - 因为C++98没有移动语义,自定义异常需要手动实现拷贝构造和赋值运算符,管理消息的内存,避免泄漏。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

