【问题标题】:How to handle a syntactically valid but logically invalid argument passed to the constructor?如何处理传递给构造函数的语法有效但逻辑无效的参数?
【发布时间】:2012-03-30 16:58:27
【问题描述】:

我需要创建一个具有如下公共接口的 Expr 类:

class Expr{
    //...
public:
   Expr(const char*);
   int eval();           //Evaluates the expression and gives the result
   void print();
};

在设计中,如果用户输入了一个无效的字符串来构造一个像“123++233+23/45”这样的Expr对象,那么最初构造Object并在调用eval()时通知错误是否正确?那个物体。

或者应该在此时检查错误本身并抛出异常,尽管这会导致运行时严重增加。并且用户可以在假设 Object 已创建并且仅在运行时发现错误的情况下进一步编写代码..

此类问题在创建类时总是会出现,是否有一种相当标准的方法来处理用户所犯的此类错误????

【问题讨论】:

  • 直接在构造函数中计算表达式?
  • here。另外,考虑标记你的构造函数explicit
  • 或者更确切地说,使用其他一些高效的代码作为静态函数仅用于该目的,我的意思是任何一种方式......

标签: c++ class error-handling


【解决方案1】:

关于如何做到这一点的唯一标准部分是完整的文档

我更喜欢尽早抛出错误,或者为这种类型的对象使用工厂——需要初始化特定参数的对象。如果您使用工厂,则可以返回 NULLnullptr 或其他任何内容。

我没有看到构造对象并仅在调用eval() 时返回错误的意义。重点是什么?反正对象是无效的,为什么要等到你使用呢?

并抛出异常,尽管这会导致严重增加 在运行时。

您对此进行了分析吗?不要使用异常,因为您假设运行时会增加。

【讨论】:

  • “当你必须失败时,尽快大声失败。”
  • 我的意思是检查会导致运行时间增加
  • @bhuwansahni:为什么?必须在 some 阶段检查表达式的有效性。
  • 另外,在构造过程中抛出异常会导致继承的严重问题,不是吗???
  • @bhuwansahni 如果您处理得当,则不会。您绝对应该阅读从构造函数中抛出异常的主题。这里有一些关于这个主题的好帖子。
【解决方案2】:
class illogical_expression_exception : public virtual exception {};

class Expr{
    //...
    int result; // store evaluated result.
public:
   explicit Expr(const char*);
   int getResult();           // Evaluate & Parse in the Constructor. 
   void print();
};

/* in constructor */

if ( ! checkExpression(expr) ) throw illogical_expression_exception();

/* in main() */
try{ Expr my_expr("2+2*2"); }
catch(const illogical_expression_exception& e){ 
   cout << "Illogical Expression." << endl; 
}

【讨论】:

  • 当然,人们会假设illogical_expression_exception 报告了导致此诊断的表达式中的位置,并解释了为什么这被认为是不合逻辑的。当然可以在catch 子句中调用e.what() 来打印诊断结果。
  • @MatthieuM。是的。但为简洁起见,我没有提及(或者说实话,忘了提及)。 :)
猜你喜欢
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 2012-09-02
  • 2019-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多