3

この種のことを行う多くのコードを含む大規模なコードベースがあります。

bool DoSomething(CString Value)
{
   if(Value == "bad")
   {
       AfxMessageBox("description of error");
       return false;
   }
   return true;
}

またはこれだけでも:

bool DoSomething(CString Value)
{
   if(Value == "bad")
   {
      return false;
   }
   return true;
}

さまざまな代替案を検討しました。

  • 例外 - 基本的に、ここで説明されているように、短所を売りにしています: http://www.codeproject.com/Articles/38449/C-Exceptions-Pros-and-Cons
  • エラーテキストが入力された追加の文字列参照パラメーターを渡す - ただし、呼び出しの前にエラー文字列を事前にインスタンス化する必要があり、パラメーターリストにバルクを追加します
  • 「last_error」メンバー変数の設定 - これは、ここで表現されている欠点に苦しんでいるようです (imo): GetLastError() は設計パターンのようなものですか? いい仕組みですか?
  • 他の関数を使用してエラーの説明にマップできる列挙型 (など) を返す - しかし、これは小さな関数やオブジェクトには「重く」感じられ、エラーが発生した場所とエラーが発生した場所の間にスペースが作成されます。メッセージは維持されます (多言語環境では、テキストの集中化を歓迎すると思いますが)。

そこで、次のような一連のクラスを作成できないかと考えました。

class CResult
{
protected:
   CResult()
   {
      // Don't have to initialize because the derived class will do it
   }
public:
   operator bool() { return m_Result; };

   bool m_Result;
   CString m_Message;
};

class CSuccess : public CResult
{
public:
   CSuccess()
   {
       m_Result = true;
   }
};

class CFailure : public CResult
{
public:
   CFailure(const CString & Message)
   {
      m_Result = false;
      m_Message = Message;
   }
};

次に、上記のコードは次のようになります。

CResult DoSomething(CString Value)
{
   if(Value == "bad")
   {
      return CFailure("description of error");
   }
   return CSuccess();
}

私が気に入っているところ:

  • コードはまだ読み取り可能で、エラー メッセージはエラー状態の近くに維持されます
  • プログラマーは、エラー状態で実際にエラー文字列を提供することを少し強制されます (はい、空白を提供することもできますが、それはもっとひどい間違いのように思えます)。
  • 呼び出し元は、関数呼び出しの前に特別な変数を作成する必要がなく、関数の結果を bool のように扱うことができます。または、エラーが無視されない場合は、簡単に説明を取得できます。
  • 次のプログラマーは、関数定義を見るだけで、どのエラー モデルが使用されているかがわかります。

私が見る主な欠点は、オブジェクトと文字列とブールがすべてインスタンス化されるという点で、成功時のオーバーヘッドが高くなることです - しかし、私たちのアプリでは多くの場合、問題のコードは検証などのパフォーマンスに敏感ではありませんユーザー入力など

私は他の大きな欠点を見逃していますか?さらに良い解決策はありますか?

4

1 に答える 1

3

「エラー」を次の2つのカテゴリに分けると便利です。

致命的なエラー

これらは、回復が意味をなさない種類のエラーです。

void check(bool cond, const string& msg)
{
  if (!cond)
  {
    // eventually log it somewhere
    std::cerr << "Fatal: " << msg << std::endl;
    exit(1);
  }
}

例外的なエラー

これらは、プログラムを実行状態に回復して維持できる種類のエラーです。

void check_ex(bool cond, const string& msg)
{
  if (!cond)
  {
    // eventually log it somewhere
    throw std::runtime_error(msg);
  }
}
于 2012-07-06T16:35:27.897 に答える