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

c++ std::exception "what()" message will always only print "std::exception" in a custom exception - why can't I get it to print the contents?

提问人:Andy 提问时间:7/1/2023 最后编辑:Remy LebeauAndy 更新时间:7/1/2023 访问量:207

问:

如果我这样做:

//... 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.

}
//... 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.
}

回复前的重要事项:

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

由于我公司的传统行业设备,我只能使用 C++98,所以我认为无法访问像 C++11 这样的更高版本。std::current_exception

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

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

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

有没有办法添加一个泛型来用于任何异常,以便我可以打印对象的消息,而不是它的超级超级父级(即)虚拟消息?我试过了,但没有用。<T>catchMyCustomExceptionstd::exceptionwhat()

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

注意:如果我抓住了,我会收到正确的消息。MyCustomException

C++ 异常 继承 C++98 对象切片

评论

5赞 Some programmer dude 7/1/2023
请注意,what 函数应该返回一个 .而且它需要合格。const char*const

答:

6赞 Ted Lyngmo 7/1/2023 #1

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

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

MyCustomException::what()需要在 C++98 中像下面这样声明才能覆盖:std::exception::what()

const char* what() const throw()

例:

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

输出:

I want to see THIS message when I fail ... but I don't...

评论

0赞 Ted Lyngmo 7/1/2023
@Eugene天哪,错过了。编辑
0赞 Andy 7/6/2023
现在这是有道理的!呃 - 我曾经有 const char* ...我不记得为什么我切换到字符串,但我会切换回来。非常感谢
0赞 Ted Lyngmo 7/6/2023
@Andy 很高兴它清除了它!别客气!
1赞 Andy 7/7/2023
再次感谢。对于其他人:我只需要做一些其他调整来匹配上面 Ted 回答的代码格式: -add virtual 到析构函数 -add “const throw()” 到 “what()” 函数。现在它正在:)工作