9

この「エラーおよび例外処理 BoostWebページの「例外クラスをどのように設計する必要がありますか?」の段落には、次のように書かれています。

[...] 3. std :: stringオブジェクト、またはコピーコンストラクタが例外をスローする可能性のあるその他のデータメンバーまたは基本クラスを埋め込まないでください。

ファイルアクセスでの実行時エラーの形式を表す例外クラスを定義する必要があるため、それをから派生させ、エラーが発生したファイル名にアクセスするための属性をstd::runtime_error追加することを考えていました。FileName()

簡単にするために、ファイル名を(Unicodeで)格納するためのデータメンバーを追加するつもりでしたstd::wstringが、前述の提案は私を止めました。では、データメンバーとして単純なバッファーを使用する必要がありますか?wchar_t

最近のデスクトップシステム(このプロジェクトのターゲットプラットフォーム)では、ファイル名の動的な文字列割り当てに注意を払うことが本当に重要ですか?そのような割り当てが失敗する可能性はどのくらいですか?組み込みシステムのような限られたリソースのシステムに対するBoostの提案は理解できますが、それは最新のデスクトップPCにも当てはまりますか?

//
// Original design, using std::wstring.
//
class FileIOError : public std::runtime_error
{
public:
    FileIOError(HRESULT errorCode, const std::wstring& filename, const char* message)
        : std::runtime_error(message),
          m_errorCode(errorCode),
          m_filename(filename)
    {
    }

    HRESULT ErrorCode() const
    {
        return m_errorCode;
    } 

    const std::wstring& FileName() const
    {
        return m_filename;
    }

private:
    HRESULT m_errorCode; 
    std::wstring m_filename;
};



//
// Using raw wchar_t buffer, following Boost's guidelines.
//
class FileIOError : public std::runtime_error
{
public:
    FileIOError(HRESULT errorCode, const wchar_t* filename, const char* message)
        : std::runtime_error(message),
          m_errorCode(errorCode)
    {
        // Safe string copy
        // EDIT: use wcsncpy_s() with _TRUNCATE, as per Hans Passant's suggestion.
        wcsncpy_s(m_filename, filename, _TRUNCATE);
    }

    HRESULT ErrorCode() const
    {
        return m_errorCode;
    } 

    const wchar_t* FileName() const
    {
        return m_filename;
    }

private:
    HRESULT m_errorCode; 
    wchar_t m_filename[MAX_PATH]; // circa 260 wchar_t's
};
4

2 に答える 2

9

そのような割り当てが失敗する可能性はどのくらいですか?

かなり低い。

通常、コードの正確さのために、その可能性がゼロかゼロでないかだけを本当に気にします。横行するオーバーコミットが原因でビルトインが::operator new決して失敗しないシステムでも、あなたのコードが を置き換えるプログラムで使用される可能性を考慮してください::operator new。または、OS が、プロセスが割り当てることを許可されているメモリの量を外部から制限する場合がありulimit -vます。

次に、失敗した場合の結果を考えてみましょう。terminate()と呼ばれます。特にそれが実際に起こる可能性は低いので、おそらくあなたはそれを受け入れることができます.

基本的に、メモリを割り当てられない場合に、適切なエラー メッセージを表示してプログラムを正常に終了さたいと思いますか? その場合は、追加のコードを記述し、エラー メッセージの長さの制限を受け入れます。Boost は汎用ライブラリ コードであるため、ユーザーが試したくないことを想定していません。

于 2012-11-17T12:43:24.457 に答える
0

C ++ 11を使用している場合は、移動セマンティクスとstd::wstringの移動コンストラクターを使用できます。これは例外ではありません。

于 2012-11-17T14:09:32.037 に答える