Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 验证输入的好方法是什么?_C++_Validation - Fatal编程技术网

C++ 验证输入的好方法是什么?

C++ 验证输入的好方法是什么?,c++,validation,C++,Validation,我有一个类,有一些成员的值是有限的。比如说 class Sphere { public: void setRadius(double radius) { m_radius = radius; } private: double m_radius; // must >= 0. }; 我还有一个对话框来输入半径。我可以在setRadius()方法中检查半径验证,也可以在对话框中检查。哪条路更好?这似乎是一个相当普遍的问题。什么是传统方式还是最

我有一个类,有一些成员的值是有限的。比如说

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

private:
    double m_radius; // must >= 0.
};
我还有一个对话框来输入半径。我可以在setRadius()方法中检查半径验证,也可以在对话框中检查。哪条路更好?这似乎是一个相当普遍的问题。什么是传统方式还是最佳方式?谢谢

我可以在setRadius()方法中检查半径验证,或者 在对话框中。哪条路更好

如果系统非常小,GUI相对简单,那么可以在dialog类中检查输入。另一种解决方案是提供第三类输入验证策略,用于检查用户输入

下面是一个非常简单的演示代码,可以使用模板为不同的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_;
};

我假设将根据用户输入调用set方法。如果是这样,传统的方法是set方法在提供异常值时抛出异常。在我看来,异常应该一直传播到UI,这是太多的面向对象了。对于少于两个三个变量,我不会创建一个包含getter setter和私有数据的类——这没有意义。它需要很多不必要的代码

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


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

在OOP中,通常在函数中进行验证,如果值不在可接受的范围内(在您的情况下),则函数会引发异常

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

  • 让您的函数返回int、bool等。如果参数在范围内,则您的函数返回某个值,指示该值。否则,函数返回一些值,指示参数不在范围内
  • 大概是这样的:

    bool setRadius(double radius)
    {
        if(radius >= 0)
        {
            m_radius = radius;
            return true;
        }
        else return false;
    }
    
    请注意,如果“radius”的参数不在您的范围内,您不会启动/更改存储在m_radius中的值。将m_半径的值更改为不可接受的值没有意义——这是浪费时间

  • 在main()中选中它(“在对话框中”)
  • 如果您想了解有关异常的更多信息,可以参考本页以更好地了解异常的含义:


    因此,我认为,惯例是在方法中检查它,如果值超出可接受的范围,则让方法抛出异常。如果您在一个类中,并且还没有涵盖异常,那么您可能不必这样做。祝你好运!:)

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

    两种方法之间存在根本区别:

    • 不允许半径变为负实际上意味着非负半径是类不变量。将所有类不变量的验证放入一个实用函数中,在所有(变化的)MemberFunction进入和退出时通过RAII助手调用该实用函数,这对于调试是一件好事,因为当内部状态(可能比单个标量更复杂)以某种方式变得不一致时,它会立即捕获。为了提高速度,我通常会对发行版二进制文件禁用这些检查,这样即使进行大量检查,也不会损失任何性能
    • 允许半径变为负值,但稍后引发异常会将其转化为使用该值的操作(例如渲染)导致的故障。在某些情况下,这会使无效输入值在该操作期间无法与内存不足区分开来,但其优点是您只需要将这些错误捕获到一个位置

    我对你的方法很感兴趣。我有很多班,只有几个成员。你的意思是公开那些成员吗?您能给我举一个非常简单的例子,说明如何使用模板保存数据并进行数据验证吗?谢谢!!首先告诉我们(在您的问题中),您在UI中使用了什么。MFC?Win32?Qt?显示一些代码!我计划使用Qt,但仍处于设计阶段。请看一看-我还没有浏览所有这些内容,但原则应该是明确的。该解决方案主要使用静态断言和动态断言,并不是数据验证的可行解决方案。您推荐的网站因其不正确和错误的文档而臭名昭著。真的吗?我经常提到它。