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中,通常在函数中进行验证,如果值不在可接受的范围内(在您的情况下),则函数会引发异常 但是,如果您正在为一个类执行此操作,并且还不需要知道如何抛出/捕获异常,则可以执行以下两种操作之一:
bool setRadius(double radius)
{
if(radius >= 0)
{
m_radius = radius;
return true;
}
else return false;
}
请注意,如果“radius”的参数不在您的范围内,您不会启动/更改存储在m_radius中的值。将m_半径的值更改为不可接受的值没有意义——这是浪费时间
因此,我认为,惯例是在方法中检查它,如果值超出可接受的范围,则让方法抛出异常。如果您在一个类中,并且还没有涵盖异常,那么您可能不必这样做。祝你好运!:) 我建议采用一种不同于其他方法的方法。我只是把价值储存在那里。相反,当在球体上调用
Render(Image&target)
函数时,请查看我的水晶球,我将在球体上验证所有参数是否合适。也可以使用混合方法,在渲染时验证球体是否在图像边界内,同时验证半径是否为setter中的非负浮点
两种方法之间存在根本区别:
- 不允许半径变为负实际上意味着非负半径是类不变量。将所有类不变量的验证放入一个实用函数中,在所有(变化的)MemberFunction进入和退出时通过RAII助手调用该实用函数,这对于调试是一件好事,因为当内部状态(可能比单个标量更复杂)以某种方式变得不一致时,它会立即捕获。为了提高速度,我通常会对发行版二进制文件禁用这些检查,这样即使进行大量检查,也不会损失任何性能
- 允许半径变为负值,但稍后引发异常会将其转化为使用该值的操作(例如渲染)导致的故障。在某些情况下,这会使无效输入值在该操作期间无法与内存不足区分开来,但其优点是您只需要将这些错误捕获到一个位置