如何创建一个派生类,它接受一个wstring并调用一个接受字符串的基类构造函数?

时间:2012-02-01 17:52:31

标签: c++ visual-studio-2010 initialization

前段时间,我在stackoverflow上发现了一个聪明的技巧,它显示了一种从runtime_error创建派生异常类的方法,它接受wstring作为构造函数。诀窍是使用虚方法调用初始化runtime_error库。这是看起来像:

UnknownEx(const std::wstring& s) throw() : m_msg(s), std::runtime_error( what() ) {};

what()进行转换(我可以将wstring转换为字符串的有损转换):

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

编译很好,但是当我尝试使用它时:

throw UnknownEx(L"Test Exception");

在尝试查找数据成员what()的长度时,应用程序在m_msg中失败。调试what()时,尚未设置m_msg。似乎初始化列表技巧中的这个函数调用不起作用。

有没有办法让这个“技巧”正常工作,还是我的整个方法被误导了?

我的长期目标:我只想创建一个派生异常类,该异常类可以通过catch(exception& ex)进行一般性捕获,但在其构造函数中接受wstring

1 个答案:

答案 0 :(得分:3)

程序崩溃是因为在std::runtime_error(what())之前执行了m_msg(s)。基类在成员变量之前初始化。

虽然在这种情况下调用what()会调用UnknownEx覆盖,但最好不要从构造函数调用虚函数,因为语义很混乱。

如果您要将异常消息存储在自己的m_msg成员变量中,请不要派生自std::runtime_error;没有理由将字符串存储两次。考虑直接从std::exception

派生