2016-07-04 12 views
1

私はユニコードの例外を除いて、ヘッダーのみのクラスを実装したいと、私は次のコードで開始しました: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; 
    } 
}; 

これは正常に動作しますが、私はいくつかの質問を持っている:

  1. なぜstd :: exceptionクラスから派生する必要がありますか?これはまったく必要ないかもしれませんか?
  2. クラスの実装で何か不足していますか?
+2

わずかな警告(とあなたの2番目の質問に関連します) :Windowsでは、 'wchar_t'はわずか16ビットです。あなたの内部エンコーディングがUTF-8の場合はプレーン 'char'を、内部的にUTF-32を使用する場合は' char32_t'を使用してください。例えば、 [この文字型リファレンス](http://en.cppreference.com/w/cpp/language/types%23Character_types#Character_types)を参照してください。 –

+1

あなたの最初の質問について:いいえ、あなたは* 'std :: exception'(http://en.cppreference)から派生する必要はありません。com/w/cpp/error/exception)、そうでなければ 'std:exception'をキャッチするプログラムはあなたの例外を捕捉せず、あなたのライブラリのために特別なケースを追加する必要があります。ああ、ところで、標準の例外を "Unicode対応の"例外と交換する場合は、既存の例外階層全体を再実装することを忘れないでください。 –

+0

最後に、この例外ライブラリには本当に必要なものがありますか?多くのコンパイラはUTF-8文字列リテラルを喜んで受け入れます。つまり、標準の標準例外で既にUnicodeを使用できることを意味します。 –

答えて

-2

これまでのところ、私がのstd ::例外クラスを派生しないことを決定しましたし、今私は、小さなきれいで素敵なUnicodeの例外クラスを持っている:

#pragma once 

#include <string> 

class uexception 
{ 
public: 
    explicit uexception(const wchar_t* umsg) : uexception(std::wstring(umsg)) { } 
    explicit uexception(const std::wstring& umsg) 
    { 
     this->umsg = umsg; 
    } 

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

private: 
    std::wstring umsg; 
}; 
5
  1. あなたはstd::exceptionを継承する必要はありません。直接継承するか、または間接的に、例外タイプの定義に依存することなく、インタフェースのユーザーがstd::exceptionを参照して例外をキャッチできるという利点があります。とにかくstd::exceptionを通じて行うことはできませんuwhatにアクセスもちろん

    、ので、あなたは、その後もあなたの設計のために望ましいかもしれないstd::exceptionを継承していない、†私の提案を実装する予定がない場合。

  2. 継承を決定した場合は、可視度をwhatに減らすことはできません。 ††

    whatの実装では、NULL終端文字列へのポインタを返さないことでstd::exceptionのインタフェースに違反します。例外ハンドラがstd::exceptionへの参照によってそれをキャッチし、what()を呼び出してポインタを参照解除すると、カオスが発生します。

    whatを実装する簡単な方法は、代わりにreturn ""になります。しかし...†

は、私が代わりを考慮しお勧めします。代わりに「何を」返さないで、あなたはネイティブの狭い文字列encondingに保存されたワイド文字列のエンコーディングを変換し、ポインタを返すことができますそれに。確かに、実装するにはもっと多くの作業が必要ですが、例外をもっと便利にすることもできます。

††技術的にはあなたが持っているとして、あなたは、uexception::whatの可視性を減らすことができますが、それはuexception::exception::whatの可視性に影響を与えることはありません。しかもそうすることはリスコフの代用原則に違反する。 std::exceptionを継承し、whatを公然と適切に実装するか、またはstd::exceptionをまったく継承しないことをお勧めします。

+0

'what()'の可視性を下げる可能性は間違いなく、ここでも良い考えかもしれません: 'uexception 'through' std :: exception'はまだ 'what()'を呼び出すことができますが、 'uexception'を直接捕まえる人は' uwhat() 'を直接呼び出すべきです。 – KABoissonneault

+0

@ KABoissonneault技術的にはyesです。私の意図する意味はもっと微妙でした。編集を参照してください。 – user2079303