1

特に複数の関数が呼び出された場合に、関数呼び出しからのエラー テストとレポートの手法を調べています。簡単にするために、各関数は bool を返します。

success = false;

if (fnOne ())
{
    if (fnTwo ())
    {
        if (fnThree ( ))
        {
            success = true;
        }
        else
        {
            cout << "fnThree failed" <<endl;
        }
    }
    else
    {
        cout << "fnTwo failed" <<endl;
    }
}
else
{
    cout << "fnOne failed" <<endl;
}

上記の例 (どこでも見られます) では、特に呼び出しコードの高さがマルチスクリーンになると、コードがすぐに読めなくなります。

現在、C ++でこれを処理する私の方法(誰かがスムーズなCテクニックを持っている場合に備えて「c」タグを含む)オブジェクトにブール値と文字列を保存します。bool は成功/失敗を表し、文字列は失敗状態の理由を表します。関数を呼び出し、関数が失敗した場合、関数はオブジェクトを内部的に失敗状態に設定し、文字列ベースの理由を提供します。私はまだこの方法に 100% 満足しているわけではありませんが、これまでのところ最高です。それがどのように見えるかの例:

void myobj::fnOne (void)
{
    if (m_fluxCapacitorProngCount > 3)
    {
        setState (false, "myobj::fnOne - Flux capacitor has been breeding again");
    }
}

void myobj::fnTwo (void)
{
    if (m_answerToLifeUniverseAndEverything != 42)
    {
        setState (false, "myobj::fnTwo - Probability drive enabled?");    
    }
}

void myobj::setup (void)
{
    // Ensure time travel is possible
    if (valid())
    {
        fnOne ();
    }

    // Ensure the universe has not changed
    if (valid())
    {
        fnTwo ();
    }

    // Error? show the reason
    if (valid() == false)
    {
        cout << getStateReason () << end;
    }
}

valid () は true/false を返し、getStateReason () はエラーが発生したときに関数で提供された文字列を返します。

私はこれが条件を入れ子にする必要なしに成長するのが好きです、私にはこれがより読みやすいと思いますが、問題があると確信しています...

複数の関数呼び出しの戻り条件の検出と報告を処理するための最良の [最もクリーンな] 方法は何ですか?

4

3 に答える 3

2

このコードは、最初のバリアントよりも明確である必要があります。

if (!fnOne ())
{
    cout << "fnOne failed" <<endl;
    return;
}
if (!fnTwo ())
{
    cout << "fnTwo failed" <<endl;
    return;
}
if (!fnThree ())
{
    cout << "fnThree failed" <<endl;
    return;
}
success = true;

一般に、C++ ではエラー処理に例外を使用できます。

于 2014-03-21T15:32:28.207 に答える
0

コード内のエラー (バグ) やユーザー入力から生じるエラーに対処することは、それ自体が大きなトピックです。採用する手法は、コードの複雑さとコードの予想寿命によって異なります。宿題プロジェクトに採用するエラー処理戦略は、学期プロジェクトに採用するエラー処理戦略よりも複雑ではありません。これは、社内プロジェクトに採用するエラー処理戦略よりも複雑ではありません。クライアントに広く配布されるプロジェクトよりも複雑ではありません。

戦略 1: エラー メッセージを書いて中止する

宿題で使用できる最も単純なエラー処理戦略は、 にメッセージを書き込んでから をstdout呼び出すことabort()です。

void fun1(int in)
{
  if (in < 0 )
  {
    printf("Can't work with a negative number.\n");
    abort();
  }

  // Rest of the function.
}

戦略 2: グローバル エラー コードを設定して返す

エラー処理の次のレベルでは、不正な入力を検出し、 を呼び出さずに処理しabort()ます。グローバルにアクセス可能なエラー コードを設定して、エラーの種類を示すことができます。このアプローチは、宿題プロジェクト、学期プロジェクト、本質的に探索的なプロジェクトに使用することをお勧めします。

void fun2(int in)
{
  if (in < 0 )
  {
    // Indicate that "fun2" came accross a NEGATIVE_INTEGER_ERROR.
    setErrorCode(NEGATIVE_INTEGER_ERROR, "fun2");
    return;
  }

  // Rest of the function.
}

void funUser(int in)
{
  // Call fun2
  fun2(in);

  // If fun2 had any errors, deal with it.
  if (checkErrorCode())
  {
     return;
  }

  // Rest of the function.
}

エラー処理の次のレベルでは、不正な入力を検出し、他のオプションを使用して処理します。関数からエラー コードが返される場合があります。C++ を使用している場合は、例外がスローされる可能性があります。これらのオプションは両方とも、大規模なプロジェクトを処理する有効な方法です。社内で行う場合でも、より広く使用するために配布する場合でも同様です。これらは、ユーザーベースが開発者チームを超えているプロジェクトに適用できます。

戦略 3: 関数からエラー コードを返す

int fun3(int in)
{
  if (in < 0 )
  {
    // Indicate that "fun3" came accross a NEGATIVE_INTEGER_ERROR.
    return NEGATIVE_INTEGER_ERROR;
  }

  // Rest of the function.
}

void funUser(int in)
{
  // Call fun3
  int ecode = fun3(in);

  // If fun3 had any errors, deal with it.
  if (ecode)
  {
     return;
  }

  // Rest of the function.
}

戦略 4: 関数からエラー コードをスローする (C++)

void fun4(int in)
{
  if (in < 0 )
  {
    // Indicate that "fun4" came accross a NEGATIVE_INTEGER_ERROR.
    throw NEGATIVE_INTEGER_ERROR;
  }

  // Rest of the function.
}

void funUser(int in)
{
  // Call fun4. Be prepared to deal with the exception or let it be
  // dealt with another function higher up in the call stack.
  // It makes sense to catch the exception only if this function do
  // something useful with it.
  fun4(in);

  // Rest of the function.
}

これにより、プロジェクトに適切なエラー処理戦略を採用するための十分な背景が得られることを願っています。

于 2014-03-21T17:03:06.023 に答える