c++ std::exception "what()" 消息将始终只在自定义异常中打印 "std::exception" - 为什么我不能让它打印内容?

And*_*ndy 1 c++ inheritance exception object-slicing c++98

如果我这样做:

//... in .h header:

class MyCustomException : public std::exception{
  private:
    string message;

  public:
    MyCustomException (string msg); //in .cpp implements "message = msg"
    ~MyCustomException() throw(){ }
    string what(); //implemented to return message.

}
Run Code Online (Sandbox Code Playgroud)
//... other code ... in cpp:

if (<blah blah blah>){
  throw MyCustomException("I want to see THIS message when I fail ... but I don't...");
}

//... more code, in cpp:

//try{<blah...>}
catch(const:: std::exception& e){
   cout << e.what() << endl << flush; //just prints "std::exception" ... same if I use "cerr" instead of cout.
}
Run Code Online (Sandbox Code Playgroud)

回复前的重要提示:

代码所在的计算机没有外部通信,所以我输入了这个......所以如果有小的明显的拼写错误,请知道我可能是正确的。

由于我公司的遗留工业设备,我一直使用 C++98,因此我认为无法访问std::current_exceptionC++11 等更高版本。

但是,我可以开始#include <cxxabi.h>工作,这使我可以<demangle>(__cxxabivl::__cxa_current_exception_type()->name())...但这仍然只是 的名称MyCustomException,而不是其what()消息。

可以尝试捕获每个异常并打印其what()消息......但应该有一种方法可以更轻松地做到这一点,对吧?

我发现文档令人困惑,并且只真正找到了一个type_info*我认为不指向实际原始异常对象的对象(理论上我可以在其中提取正确的what()消息)。

有没有办法添加一个<T>用于catch任何异常的泛型,以便我可以打印MyCustomException对象的消息,而不是其超级父级(即std::exception)虚拟what()消息?我尝试过,但没有成功。

注意:是的,我使用catch(const std::exception e)...但是打印父级的“对象切片”问题仍然发生。

注意:如果我捕获MyCustomException,我会收到正确的消息。

Ted*_*gmo 6

您没有经历“对象切片”,因为您没有exception按值捕获。

std::exception::what()是一种virtual方法,但您根本没有正确覆盖它,这就是为什么MyCustomException::what()没有按预期调用的原因。如果您使用的是 C++11 或更高版本,则可以使用override关键字在编译时捕获此错误,但该选项在 C++98 中不可用。

MyCustomException::what()需要在 C++98 中声明如下以覆盖std::exception::what()

const char* what() const throw()
Run Code Online (Sandbox Code Playgroud)

例子:

#include <exception>
#include <iostream>
#include <string>

class MyCustomException : public std::exception {
public:
    MyCustomException(const std::string& msg) throw() : message(msg) {}
    virtual ~MyCustomException() throw() {}

    const char* what() const throw() { return message.c_str(); }

private:
    std::string message;
};

int main() {
    try {
        throw MyCustomException(
            "I want to see THIS message when I fail ... but I don't...");
    } catch (const std::exception& e) {
        std::cout << e.what() << '\n';
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

I want to see THIS message when I fail ... but I don't...
Run Code Online (Sandbox Code Playgroud)