-1

値の範囲が有限のメンバーを持つクラスがあります。例えば

class Sphere
{
public:
    void setRadius(double radius)
    {
        m_radius = radius;
    }

private:
    double m_radius; // must >= 0.
};

半径を入力するダイアログもあります。setRadius() メソッドで半径の検証を確認するか、ダイアログで確認できます。どちらの方法が良いですか?これはかなり一般的な問題のようです。従来の方法または最善の方法は何ですか? ありがとう。

4

5 に答える 5

3

setメソッドはユーザー入力に基づいて呼び出されると思います。その場合、従来の方法は、例外的な値が提供された場合にsetメソッドが例外をスローすることです。例外はUIまで伝播する必要があります

于 2013-01-20T05:04:21.603 に答える
1

setRadius()メソッドで半径の検証を確認するか、ダイアログで確認できます。どちらが良いですか?

システムが非常に小さく、GUIが比較的単純な場合は、ダイアログクラスの入力を確認できます。もう1つの解決策は、ユーザー入力をチェックする入力検証ポリシーとして3番目のクラスを提供することです。

以下は非常に単純なデモストレーションコードで、テンプレートを使用してさまざまなGUIにさまざまなポリシーを設定できます。

class CheckPolicy
{
public:
  CheckPolicy() {}

  virtual bool ValidInput(double f)
  {
    return f > 0;
  }
};

class GUI
{
public:
  GUI(){}
  void GetInput()
  {
      float f = 1.0f;
      if (policy_.ValidInput(f))
      {
        sphere_.setRadius(f);
      }
  }
private:
  CheckPolicy policy_;
  Sphere      sphere_;
};
于 2013-01-20T05:04:06.527 に答える
1

ここでは、他のアプローチとは異なるアプローチをお勧めします。そこに値を保存するだけです。Render(Image& target)代わりに、すべてのパラメーターが適合することを検証する場所である球で関数を呼び出すときに、水晶玉を調べます。また、レンダリング時に球が画像の境界内にあることを確認しながら、セッターで半径が非負の浮動小数点数であることを検証するハイブリッド アプローチも可能です。

と のアプローチには根本的な違いがあります。

  • 半径が実質的に負になることを許可しないということは、非負の半径がクラス不変であることを意味します。すべてのクラス不変条件の検証をユーティリティ関数に入れ、すべての (変化する) メンバー関数の開始時と終了時に RAII ヘルパーを介して呼び出すことは、デバッグに適しています。単一のスカラーよりも複雑な) は、何らかの形で一貫性がなくなります。速度を上げるために、私は通常、リリース バイナリのこれらのチェックを無効にしているため、大規模なチェックを行ってもパフォーマンスが低下することはありません。
  • 半径が負になることを許可し、後で例外を発生させると、値を使用する操作 (レンダリングなど) によって引き起こされる障害になります。場合によっては、これにより、その操作中に無効な入力値とメモリ不足を区別できなくなりますが、これらのエラーを 1 か所でトラップするだけでよいという利点があります。
于 2013-01-20T09:31:35.200 に答える
1

OOPでは、通常、関数で検証を行い、値が許容範囲内にない場合は関数に例外をスローさせます。

ただし、クラスに対してこれを行っていて、例外のスロー/キャッチについてまだ知らない場合は、次の 2 つのいずれかを行うことができます。

  1. 関数が int、bool などを返すようにします。引数が範囲内にある場合、関数はそのことを示す値を返します。それ以外の場合、関数は、引数が範囲内になかったことを示す値を返します。

このようなもの:

bool setRadius(double radius)
{
    if(radius >= 0)
    {
        m_radius = radius;
        return true;
    }
    else return false;
}

「半径」の引数が範囲内にない場合、m_radius に格納されている値を開始/変更しないことに注意してください。m_radius の値を許容できない値に変更しても意味がありません。時間の無駄です。

  1. main() で確認してください (「ダイアログで」?)

例外について詳しく知りたい場合は、このページを参照して、例外とは何かをより深く理解してください: http://www.cplusplus.com/doc/tutorial/exceptions/

したがって、i++ と結論として、慣習はメソッドでそれをチェックし、値が許容範囲外の場合はメソッドに例外をスローさせることです。ただし、クラスにいて、まだ例外をカバーしていない場合は、必要ないかもしれません。頑張ってください!:)

于 2013-01-20T05:42:57.127 に答える
0

私の意見では、それはオブジェクト指向が多すぎると思います。変数が 2 ~ 3 個未満の場合は、getter-setter とプライベート データを持つクラスを作成しません。意味がありません。多くの不要なコードが必要です。

UIフロントでデータ検証を行う方がよいでしょう(たとえば、を介してDoDataExchange)。

データを保持し、データ検証を行うクラスを考案する必要がある場合は、テンプレートを使用してください。

于 2013-01-20T05:14:14.547 に答える