簡體   English   中英

驗證輸入的好方法是什么?

[英]What is a good way to validate input?

我有一類帶有一些成員的類,其值的范圍是有限的。 例如

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

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

我也有一個對話框來輸入半徑。 我可以在setRadius()方法中檢查半徑驗證,或在對話框中檢查。 哪種方法更好? 這似乎是一個普遍的問題。 什么是常規方式或最佳方式? 謝謝。

我假設將根據用戶輸入調用set方法。 如果是這樣,則常規方法是如果提供了異常值,則set方法將引發異常。 異常應該一直傳播到用戶界面

我可以在setRadius()方法中檢查半徑驗證,或在對話框中檢查。 哪種方法更好?

如果系統非常小且GUI相對簡單,則可以檢查對話框類中的輸入。 另一種解決方案是提供第三類作為輸入驗證策略,以檢查用戶輸入。

下面是一個非常簡單的演示代碼,可以使用模板為不同的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_;
};

在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 ++並得出結論,慣例是在方法中對其進行檢查,如果值超出可接受范圍,則使該方法引發異常。 如果您在課堂上並且還沒有涵蓋異常,則可能不必這樣做。 祝您好運! :)

我建議使用與此處其余方法不同的方法。 我只是將值存儲在那里。 相反,當我在球體上調用Render(Image& target)函數時,要檢查我的水晶球,在該球體上,我將驗證所有參數是否合適。 混合方法也是可行的,您可以在渲染時驗證半徑是否在設置器中為非負浮點,同時驗證球體是否在圖像的邊界內。

與方法之間存在根本的區別:

  • 不允許半徑有效地變為負數意味着非負半徑是一類不變式。 將所有類不變量的驗證放到在所有(變異)成員函數的入口和出口處通過RAII助手調用的實用程序函數中進行調試是一件好事,因為它會在內部狀態(可能會更多)時立即捕獲比單個標量復雜)在某種程度上變得不一致。 為了提高速度,我通常對發布二進制文件禁用這些檢查,因此即使進行大量檢查,您也不會損失任何性能。
  • 允許半徑變為負數,但是稍后引發異常將其轉變為由使用該值的操作(例如渲染)引起的故障。 在某些情況下,這會使無效輸入值在該操作期間無法與內存不足區分開來,但是其優點是您只需要將這些錯誤捕獲在一個位置即可。

我認為,這太過面向對象。 對於少於三分之二的變量,我不會創建一個具有getter-setter和私有數據的類-這沒有任何意義。 它需要很多不必要的代碼。

您最好在UI前端進行數據驗證(例如,通過DoDataExchange )。

如果必須設計一個類來保存數據並進行數據驗證,請使用模板!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM