Some time ago, I found a clever trick on stackoverflow that showed a way to create a derived exception class from runtime_error that accepts a wstring as a constructor. The trick was to initialize the runtime_error base with a virtual method call. Here’s what that looks like:
UnknownEx(const std::wstring& s) throw() : m_msg(s), std::runtime_error( what() ) {};
And what() does the conversion (I’m okay with the lossy conversion from wstring to string):
virtual const char* what() const throw() {
// Convert the wstring data member to a char*.
const wchar_t* wstr = m_msg.c_str();
char *str = new char[wcslen(wstr)];
size_t *charsChanged = 0;
wcstombs_s(charsChanged, str, sizeof(str), wstr, _TRUNCATE);
return str;
}
This compiles fine, but when I try to utilize it:
throw UnknownEx(L"Test Exception");
The application fails in the midst of what() when trying to find the length of the data member m_msg. When debugging into what(), m_msg hasn’t yet been set. It seems this function call in the initializer list trick isn’t working.
Is there a way to get this “trick” to work properly, or is my entire approach misguided?
My long term goal: I would simply like to create a derived exception class that is able to be caught generically with catch(exception& ex), but accepts a wstring in its constructor.
The program crashes because
std::runtime_error(what())is executed beforem_msg(s). Base classes are initialized before member variables.While your call to
what()will in this case call yourUnknownExoverride, it’s best not to call virtual functions from constructors, because the semantics are confusing.If you are going to store your exception message in your own
m_msgmember variable, don’t derive fromstd::runtime_error; there’s no reason to store the string twice. Consider deriving directly fromstd::exception.