2016-07-04 26 views
1

我想要實現使用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; 
    } 

    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

有輕微的警告(以及相關的第二個問題) :在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來捕捉異常 - 而不依賴於異常類型的定義。

    當然,訪問uwhat通過std::exception將是不可能的,無論如何,所以如果你不打算執行我的建議,那麼不繼承std::exception甚至可能希望爲您的設計。

  2. 如果您決定繼承,那麼減少what的可見性是不可能的。 ††

    你實現what通過不返回一個指向空結尾的字符串違反std::exception接口。如果異常處理程序通過引用std::exception來捕獲該異常,則調用what()並取消引用該指針,則會出現混亂。

    實施what的一個簡單方法是改爲return ""。然而...

我建議考慮一種替代方案:與其將「無」,你可以在存儲寬字符串的編碼轉換爲本地窄字符串enconding並返回一個指針對此。當然,這將是更多的工作來執行,但也會讓你的例外更方便。

††從技術上講可以降低能見度uexception::what,因爲你有,但它並不影響uexception::exception::what知名度。此外,這樣做違反了Liskov替代原則。我建議你繼承std::exception並公開執行what,或者根本不繼承std::exception

+0

降低「what()」的可見性肯定是一種可能性,在這裏甚至可能是一個好主意:客戶誰趕上'uexception '通過'std :: exception'仍然可以調用'what()',但那些直接接收'uexception'的應該調用'uwhat()'。 – KABoissonneault

+0

@KABoissonneault在技術上是的。我的意圖更加微妙。查看編輯。 – user2079303