1

if I do this:

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

Important notes before replying:

The computer the code is on doesn't have outside communication, so I typed this ... so if there is small obvious typos, know I probably have it correct.

Due to my company's legacy industry equipment, I am stuck with C++98, so do not have access to std::current_exception which is with a later version like C++11, I think.

However, I can get #include <cxxabi.h> to work, which allows me to <demangle>(__cxxabivl::__cxa_current_exception_type()->name()) ... but that is still just the name of MyCustomException, not its what() message.

I could try to catch each individual exception and print its what() message ... but there should be a way to do it easier, right?

I found the documentation confusing and only really found a type_info* that I don't think points to the actual original exception object (wherein I could theoretically extract the proper what() message).

Is there a way to add a generic <T> to be used in a catch for any exception so that I can print MyCustomException object's message, and not its super super parent's (i.e. std::exception) virtual what() message? I tried but it didn't work.

Note: Yes, I use catch(const std::exception e) ... yet the "Object Slicing" problem of printing the parent still occurs.

Note: If I catch MyCustomException, I get the proper message.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Andy
  • 33
  • 3
  • 5
    Please note that the [`what`](https://en.cppreference.com/w/cpp/error/exception/what) function is supposed to return a `const char*`. And it needs to be `const` qualified. – Some programmer dude Jun 30 '23 at 17:43

1 Answers1

6

You are not experiencing "object slicing" since you are not catching the exception by value.

std::exception::what() is a virtual method, but you are simply not overriding it correctly, which is why MyCustomException::what() is not being called as expected. If you were using C++11 or later, you could use the override keyword to catch this mistake at compile-time, but that option is not available in C++98.

MyCustomException::what() needs to be declared like the following in C++98 to override std::exception::what():

const char* what() const throw()

Example:

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

Output:

I want to see THIS message when I fail ... but I don't...
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • @Eugene Jeez, missed that. Editing – Ted Lyngmo Jun 30 '23 at 17:54
  • That makes sense now! Ugh - I used to have const char* ... I don't remember why I switched to string but I'll switch back. Thanks so much – Andy Jul 05 '23 at 17:42
  • @Andy Glad it cleared it up! You're welcome! – Ted Lyngmo Jul 05 '23 at 17:44
  • 1
    Thanks again. For anyone else: I just had to do a few other tweaks to match the code format of Ted's answer above: -add virtual to the destructor -add "const throw()" to the "what()" function. Now it is working :) – Andy Jul 06 '23 at 23:06