2

C++で静的エラー文字列を処理するための最良の方法について意見をお願いします。私は現在、いくつかの定数charポインターを使用していますが、扱いにくく、コード内のいたるところに散在しています。また、これらの文字列に静的定数charポインターを使用する必要がありますか?

クロスプラットフォームの互換性のためにSimpleIniクラスを使用して、定義、ハッシュテーブル、およびINIファイルについて考えていました。プロジェクトは常に実行されているWebサーバーです。

エラー番号や名前を使って論理的に参照したいと思います。

それが役立つ場合は、名前空間クラスに含まれるグローバルスペースとメソッドを使用しています。それが役立つ場合は、環境のためにコードがCにエクスポートされます。

ありがとう

4

4 に答える 4

2

まず、stackoverflowに関する他の関連する質問を確認できます。ここにいくつかあります:

次に、エラー処理に関するこの優れたチュートリアルをご覧ください(これは5部構成のチュートリアルですが、そのリンクからすべてにアクセスできます)。これは、C ++ 11を使用している場合に特に興味深いものです。これは、エラー処理のためのより多くの機能を提供するためです。または、C ++ 11を使用できない場合は、ブーストを使用できます。

また、ローカリゼーションのサポートを含めるかどうかも検討する必要があります。アプリケーションが異なる言語でユーザーにメッセージを表示する可能性がある場合は、その要件を最初からエラー管理にも含めるとよいでしょう。たとえば、 Boost.Localeでそのことを確認できます。

于 2012-05-26T15:56:39.323 に答える
2

ここで緊張していることがいくつかあるので、それらを列挙させてください。

  • 集中化/モジュール性:集中化について考えるのが普通です。これにより、予想されるエラーの種類を簡単にチェックし、おおよそのお土産などからエラーを回復できます。ただし、モジュール性では、各モジュールが新しいエラー
  • 動的初期化中にエラーが発生する可能性があります(コードの実行を禁止しない限り、チェックは簡単ではありません)。存続期間の問題を回避するには、静的初期化中に初期化されるオブジェクトのみに依存することをお勧めします(これは文字列リテラルの場合です)。 、 例えば)

一般に、私が見た中で最も単純なことは、ある積分定数を使用してエラーを識別し、次に他の情報(潜在的には多くの情報)を取得できる側にテーブルを置くことでした。たとえば、Clangはこのシステムを診断に使用します。プリプロセッサを有利に使用することで、繰り返しを避けることができます。

次のようなヘッダーを使用します。

#define MYMODULE_ERROR_LIST     \
     ERROR(Code, "description") \
     ...

#define ERROR(Code, Desc) Code,

class enum ErrorCode: unsigned {
    MYMODULE_ERROR_List
    NumberOfElements
};

#undef ERROR

struct Error {
    ErrorCode code;
    char const* description;
};

Error const& error(ErrorCode ec);

そして、配列を見つけるための簡単なソースファイル:

#define ERROR(Code, Desc) { Code, Desc },

Error const ErrorsArray[] = {
    MYMODULE_ERROR_LIST
    {ErrorCode::NumberOfElements, 0}
};

Error const& error(ErrorCode const ec) {
    assert(unsigned(ec) < unsigned(ErrorCode::NumberOfElements) &&
           "The error code must have been corrupted.");
    return ErrorsArray[ec];
} // error

注:ヘッダーでマクロを定義することの代償は、説明の文言のわずかな変更が、列挙型に応じてすべてのコードの再コンパイルを意味することです。個人的には、私のものはテストされたものよりもはるかに速く構築されるので、私はあまり気にしません。

これは非常に効率的なスキームです。DRY(Do n't Repeat Yourself)を尊重するため、コード記述マッピングが正確であることも保証されます。マクロを調整して、説明だけでなく、より多くのERROR情報(カテゴリなど)を含めることができます。Errorタイプがである限りis_trivially_constructible、配列は静的に初期化できるため、ライフタイムの問題を回避できます。

残念ながら、enumモジュール性はあまり得意ではありません。また、各モジュールに独自の機能を持たせるenumことは、エラーを均一に処理することになるとすぐに退屈になる可能性があります(Error構造体はを使用できますunsigned code;)。

中央リポジトリを超えたい場合は、より複雑なメカニズムが必要ですが、それがあなたに適しているように思われたので、この制限については言及しません。

于 2012-05-26T16:18:21.827 に答える
1

ヘッダーで、シンプルに保ちます。

enum ErrorCode { E_help, E_wtf, E_uhoh };
const char* errstr(ErrorCode);

次に、いくつ.cかの.ccファイルで:

const char* error_strings[] = {
  "help!",
  "wtf?",
  "uh-oh"
};
const char* errstr(ErrorCode e) { return error_strings[e]; }
于 2012-05-26T15:47:17.200 に答える
-1

あなたの質問の詳細はあまりありませんが、あなたが投稿したものを使用して、エラーメッセージを処理するためのシングルトンクラスを検討します。コード番号または列挙型でメッセージにアクセスするためのメソッドを作成できます。次に、国際化など、特定のアプリケーションに必要なものを実装できます。また、将来SQLiteまたはその他のファイルベースのソリューションを使用することにした場合でも、クラスインターフェイスはそのまま(または拡張)にして、残りのコードへの影響を最小限に抑えることができます。

于 2012-05-26T15:42:28.677 に答える