この「エラーおよび例外処理」 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
};