C++ Unicode异常类

C++ Unicode异常类,c++,exception,unicode,C++,Exception,Unicode,我想实现带有unicode异常的仅标头类,我从以下代码开始: #pragma once #include <string> #include <exception> using namespace std; class uexception : public exception { public: explicit uexception(const wchar_t* msg) { this->msg = msg; }

我想实现带有unicode异常的仅标头类,我从以下代码开始:

#pragma once

#include <string>
#include <exception>

using namespace std;

class uexception : public exception
{
public:
    explicit uexception(const wchar_t* msg)
    {
         this->msg = msg;
    }

    explicit uexception(const wstring& msg)
    {
         this->msg = msg;
    }

    const wchar_t* uwhat() const throw ()
    {
        return msg.c_str();
    }

private:
    wstring msg;

    const char* what() const throw () //hidden
    { 
        return NULL;  
    } 
};
这很好,但我有一些问题:

为什么我需要从std::exception类派生?这可能根本不需要吗? 我是否在课堂实施中遗漏了什么? 您不必继承std::exception。直接或间接继承它的优点是允许接口用户通过引用std::exception捕获异常,而不依赖于异常类型的定义

当然,无论如何通过std::exception访问不可能的uw,因此如果您不打算实现我的建议†,那么不继承std::exception甚至可能是您的设计所需要的

如果您决定继承,则降低不可能的可见性。†

通过不返回指向以null结尾的字符串的指针,您实现了违反std::exception接口的内容。如果异常处理程序通过引用std::exception捕捉到该异常,调用what并取消对指针的引用,那么混乱就会接踵而至

一种实现返回的简单方法。但是…†

†我建议考虑另一种选择:您可以将存储的宽字符串编码转换为本机窄字符串编码,并返回指向该编码的指针,而不是什么也不返回。当然,这将需要执行更多的工作,但也会使您的异常更加方便

††从技术上讲,您可以降低UEException::what的可见性,但这不会影响UEException::exception::what的可见性。此外,这样做违反了利斯科夫替代原则。我建议您要么继承std::exception并正确地公开实现它,要么根本不继承std::exception

您不必继承std::exception。直接或间接继承它的优点是允许接口用户通过引用std::exception捕获异常,而不依赖于异常类型的定义

当然,无论如何通过std::exception访问不可能的uw,因此如果您不打算实现我的建议†,那么不继承std::exception甚至可能是您的设计所需要的

如果您决定继承,则降低不可能的可见性。†

通过不返回指向以null结尾的字符串的指针,您实现了违反std::exception接口的内容。如果异常处理程序通过引用std::exception捕捉到该异常,调用what并取消对指针的引用,那么混乱就会接踵而至

一种实现返回的简单方法。但是…†

†我建议考虑另一种选择:您可以将存储的宽字符串编码转换为本机窄字符串编码,并返回指向该编码的指针,而不是什么也不返回。当然,这将需要执行更多的工作,但也会使您的异常更加方便


††从技术上讲,您可以降低UEException::what的可见性,但这不会影响UEException::exception::what的可见性。此外,这样做违反了利斯科夫替代原则。我建议您要么继承std::exception并正确地公开实现它,要么根本不继承std::exception。

一个轻微的警告,与您的第二个问题有关:在Windows上,wchar\u t只有16位。如果内部编码为UTF-8,请使用纯字符;如果内部编码为UTF-32,请使用字符32\t。有关第一个问题的更多信息,请参见,例如:否,您不需要从中派生,但如果您不这样做,则捕获std:exception的程序将不会捕获您的异常,并且需要为您的库添加特殊情况。哦,顺便说一下,如果你想用Unicode感知的异常交换标准异常,别忘了重新实现整个现有的异常层次结构。最后,真的需要这个异常库吗?许多编译器会乐意接受UTF-8字符串文本,这意味着在正常的标准异常中已经可以使用Unicode;一般来说,尤其不是在头中,因为你会为每个人(包括你的头)指定全局名称空间,这不是一件好事。@JoachimPileborg:根据平台惯例解码的标准消息。在Windows中使用UTF-8将是一种至少偶尔将文本置乱到无法识别的方式。但对于那些移植Unixland程序甚至不能处理Windows路径的人来说,这是一个强烈的建议。我最让人大开眼界的经历之一是使用Qt安装程序,有一次:它不能处理退格,就像我在20世纪90年代使用过的所有Unix编辑器都存在令人困惑的键盘问题一样,这是一个小小的警告,与您的第二个问题有关:在Windows上,wchar\u t仅为16 bi
ts.如果内部编码为UTF-8,则使用纯字符;如果内部编码为UTF-32,则使用字符32\u t。有关第一个问题的更多信息,请参见,例如:否,您不需要从中派生,但如果您不这样做,则捕获std:exception的程序将不会捕获您的异常,并且需要为您的库添加特殊情况。哦,顺便说一下,如果你想用Unicode感知的异常交换标准异常,别忘了重新实现整个现有的异常层次结构。最后,真的需要这个异常库吗?许多编译器会乐意接受UTF-8字符串文本,这意味着在正常的标准异常中已经可以使用Unicode;一般来说,尤其不是在头中,因为你会为每个人(包括你的头)指定全局名称空间,这不是一件好事。@JoachimPileborg:根据平台惯例解码的标准消息。在Windows中使用UTF-8将是一种至少偶尔将文本置乱到无法识别的方式。但对于那些移植Unixland程序甚至不能处理Windows路径的人来说,这是一个强烈的建议。我最让人大开眼界的经历之一是使用Qt安装程序,有一次:它不能处理退格,就像我在20世纪90年代使用过的所有Unix编辑器都出现了令人困惑的键盘问题一样,降低了某种可能性的可见性,甚至可能是一个好主意:通过std::exception捕获UEException的客户端仍然可以调用what,但那些直接发现UEException的人应该改称uwhat。@KABoissonneault技术上是的。我的本意更加微妙。请参阅编辑。降低一定可能性的可见性,甚至可能是一个好主意:通过std::exception捕获UEException的客户端仍然可以调用what,但直接捕获UEException的客户端应该调用uwhat。@KABoissonneault技术上是的。我的本意更加微妙。请参见编辑。