【问题标题】:Conversion function for error checking considered good?用于错误检查的转换函数算不算好?
【发布时间】:2011-09-08 16:41:57
【问题描述】:

我想要一种简单的方法来检查对象是否有效。我想到了一个简单的转换函数,像这样:

operator bool() const { return is_valid; }

现在检查它是否有效会非常简单

// is my object invalid?
if (!my_object) std::cerr << "my_object isn't valid" << std::endl;

这被认为是一种好习惯吗?

【问题讨论】:

    标签: c++ error-handling


    【解决方案1】:

    在C++03中,你需要使用safe bool idiom来避免邪恶的事情:

    int x = my_object; // this works
    

    在 C++11 中,您可以使用显式转换:

    explicit operator bool() const
    {
        // verify if valid
        return is_valid;
    }
    

    这样你需要明确转换为 bool,这样你就不能再意外地做一些疯狂的事情(在 C++ 中你总是可以故意做一些疯狂的事情):

    int x = my_object; // does not compile because there's no explicit conversion
    bool y = bool(my_object); // an explicit conversion does the trick
    

    这在ifwhile 等需要布尔表达式的地方仍然正常工作,因为这些语句的条件根据上下文转换为布尔:

    // this uses the explicit conversion "implicitly"
    if (my_object)
    {
        ...
    }
    

    这在 §4[conv] 中有记录:

    表达式e 可以是隐式的 转换为类型T当且仅当 声明T t=e; 格式正确, 对于一些发明的临时变量t (§8.5)。某些语言结构 要求表达式是 转换为布尔值。一个 表达式e出现在这样一个 context 被称为 contextually 转换为 bool 并且格式正确 当且仅当声明 bool t(e); 格式正确,对于某些人来说 发明了临时变量t(第 8.5 节)。两者的效果 隐式转换与执行 声明和初始化,然后使用临时 作为转换结果的变量。

    (不同之处在于使用bool t(e);而不是bool t = e;。)

    这种上下文转换为布尔值的地方是:

    • ifwhilefor 语句的条件;
    • 逻辑否定运算符!、逻辑合取&amp;&amp;、逻辑析取||
    • 条件运算符?:;
    • static_assert 的条件;
    • noexcept 异常说明符的可选常量表达式;

    【讨论】:

    • 很高兴知道if 等进行了显式转换!有什么标准参考吗?并且确定不只是 ! 能达到目的吗? :)
    • "使用显式转换"隐式""——我喜欢这个说法,这是一个很好的悖论。
    • “所以你不能再意外地做疯狂的事情(在 C++ 中你总是可以故意做疯狂的事情)”让我笑了。 :-)
    【解决方案2】:

    ,一个简单的 bool 转换运算符是 not,因为您现在可以在 不相关的类型之间进行恶意比较。一般来说,是的,转换函数是可以的。只需使用the right one (safe-bool idiom)。我无法比给定的链接更好地解释它。

    【讨论】:

      【解决方案3】:

      原来的问题是

      这被认为是一种好习惯吗?

      安全布尔转换的问题在实践中非常重要,但幸运的是现在已经被标准解决了。

      但是判断这种方法是否合适,是一个设计问题。

      通过引入这样的“有效性检查”,您实际上是在声明您的对象可能处于无效状态。也就是说,用计算机科学的术语来说,您向对象表示的值域添加了一个新的单独值。所谓的底价

      具有该属性的值域最突出的示例是指针。指针可以指向不同的内存位置,但也可以是NULL(无效)。

      因此,我们需要问问自己:这样一个底值是否真的反映了我们想要用我们的类建模的事物的性质————我们真的需要涵盖以下方面吗?我们模型中的性质?

      经验表明,底部值往往容易出错、容易忘记,而且通常更多的是一种负债而不是资产。如果您能够以您的对象不会无效的方式安排您的代码,那么您的代码就会变得更简单、更易于阅读、理解和维护。..

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-19
        • 2021-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多