【问题标题】:Have I to throw an exception?我要抛出异常吗?
【发布时间】:2012-07-06 19:20:08
【问题描述】:

假设我的类有一个静态方法,它返回一个与我的类相同类型的对象。例如,要创建对象,此方法必须解析一个字符串:

class C
{
public:

   static C get_obj(const std::string& str)
   {
      C obj;
      // Parse the string and set obj properties
      return obj;
   }
};

如果在解析字符串时出现错误,并且无法将对象构造为有效对象,我是否应该抛出异常或其他什么?

【问题讨论】:

    标签: c++ exception


    【解决方案1】:

    鉴于get_obj 中存在失败的可能性,必须以某种方式将失败报告给调用者。这通常由

    • 抛出异常
    • 在方法的输出中传达故障

    在这种特殊情况下,该方法的唯一输出是C 实例。鉴于抛出异常可能是此签名方法的最佳选择。唯一的其他选择是将成功/失败嵌入到您几乎肯定不想这样做的C 对象中。

    解决此问题的另一种方法是try_parse 模式。让bool return 表示成功/失败,并通过引用参数成功返回构造对象

    bool try_parse(const std::string& str, C& obj) {
      if (string is valid) { 
        obj = C(...);
        return true;
      }
    
      return false;
    }
    

    【讨论】:

    • 你会如何调用你的try_parse 函数?使用默认构造的C 对象?
    • @Prætorian 是的。如果您从原始问题中注意到,尽管这似乎是C 支持的场景,因为作者在get_obj 的实现中这样做了。除非使用默认构造函数,否则我将使用 `shared_ptr& 或类似机制
    • 它是这样工作的,但 IMO 调用看起来很难看。 C foo; if( !try_parse( "blah", foo ) ) { /* Error, do something */ }。也可以是C foo( "blah" );try-catch 包围。除非您动态分配对象,否则没有真正干净的方法来实现 try_parse
    • @Prætorian 也不太喜欢代码。但是在C 具有有效默认构造的情况下,我更喜欢它而不是动态分配
    【解决方案2】:

    我会说你应该抛出一个异常。这样你通知客户端无法获取 obj,并强制他处理。

    如果不重要(不重要),您可以返回一个特殊的C,它可以作为指示出现问题的标记值。客户会选择是否做某事。

    我会例外。不推荐第二种方法。

    【讨论】:

      【解决方案3】:

      是的,抛出异常是完全有效的。 与构造对象的原因相同,如果无法继续构造对象,则别无选择,只能抛出异常。

      【讨论】:

        【解决方案4】:

        是的,您确实需要抛出异常。

        class C
        {
        public:
        
           static C get_obj(const std::string& str)
           {
              try
              {
                  C obj;
                  // Parse the string and set obj properties
                  return obj;
              }
              catch (int x)
              {
                cout "blahblah";
              }
           }
        };
        

        如果无法构造对象,您将面临 0 变量的风险,这可能会导致更多麻烦

        【讨论】:

        猜你喜欢
        • 2013-05-20
        • 1970-01-01
        • 2013-05-27
        • 1970-01-01
        • 1970-01-01
        • 2015-12-10
        • 2018-03-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多