-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 设置不同的策略。

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

在 OOP 中,您通常在函数中进行验证,如果值不在您接受的范围内,则让函数抛出异常。

但是,如果您正在为一个类执行此操作并且预计还不知道抛出/捕获异常,您可以执行以下两项操作之一:

  1. 让你的函数返回一个 int、bool 等。如果参数在范围内,那么你的函数会返回一些值来表明这一点。否则,该函数返回一些值,指示参数不在范围内。

像这样的东西:

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

请注意,如果“radius”的参数不在您的范围内,您不会启动/更改存储在 m_radius 中的值。将 m_radius 的值更改为不可接受的值是没有意义的——这是浪费时间。

  1. 在 main() 中检查它(“在对话框中”?)

如果您想了解更多有关异常的信息,可以参考此页面以更好地了解异常是什么:http ://www.cplusplus.com/doc/tutorial/exceptions/

因此,i++ 总结起来,约定是在方法中检查它,如果值超出可接受的范围,则让方法抛出异常。如果您在上课并且尚未涵盖异常,则可能不必这样做。祝你好运!:)

于 2013-01-20T05:42:57.127 回答
1

我建议采用与此处其他方法不同的方法。我只是将价值存储在那里。相反,查看我的水晶球,当调用Render(Image& target)球体上的函数时,我将验证所有参数是否适合。也可能是一种混合方法,您可以在设置器中验证半径是非负浮点数,同时在渲染时验证球体是否在图像的边界内。

to 方法之间有一个根本的区别:

  • 不允许半径有效地变为负数意味着非负半径是类不变量。将所有类不变量的验证放入一个实用函数中,通过 RAII 助手在所有(变异)成员函数的进入和退出时调用该函数对于调试来说是一件好事,因为它会立即捕获内部状态(可能更多复杂的不仅仅是一个标量)在某种程度上变得不一致。为了速度,我通常禁用这些对发布二进制文件的检查,因此即使进行大量检查,您也不会失去任何性能。
  • Allowing the radius to become negative but raising exceptions later turns this into a fault caused by the operation (e.g. rendering) that uses the value. In some cases, this makes the invalid input value indistinguishable from an out-of-memory during that operation, but it has the advantage that you only need to trap these errors in one place.
于 2013-01-20T09:31:35.200 回答
0

在我看来,这太过分了面向对象。对于少于两三个变量,我不会创建一个具有 getter-setter 和私有数据的类——这没有意义。它需要很多不必要的代码。

您最好在 UI 前端进行数据验证(例如通过DoDataExchange)。

如果您必须设计一个类来保存数据并进行数据验证,请使用模板!

于 2013-01-20T05:14:14.547 回答