C ++运算符重载错误检查无一例外

杰杰

我有一个类似的类vector,主要是动态大小的数组。我正在为资源有限的平台编写它,因此我必须不要使用异常。

显然,使用运算符重载来简化此类的接口,必须在某些运算符重载函数中执行动态分配。赋值运算符(=)是一个示例。

但是,没有例外,以合理的方式通知调用者错误的分配错误,同时仍然要恢复强大的错误安全性,这是相当具有挑战性的。我可能具有该类的error属性,在每次涉及动态分配的调用之后,调用方都必须检查该类的错误属性,但这似乎不是一个最佳解决方案。

编辑:

这是我目前所拥有的最好的主意(在上段中以不太理想的解决方案突出显示),任何改进将不胜感激:

dyn_arr & dyn_arr::operator=(dyn_arr const & rhs) {
    if (reallocate(rhs.length)) // this does not destroy data on bad alloc
       error |= bad_alloc; // set flag indicating the allocate has failed
    else {
        size_t i;
        for (i = 0; i < rhs.length; ++i) // coppy the array
            arr[i] = rhs.arr[i]; // assume this wont throw an exceptions and it wont fail
    }
    return *this;
}

然后致电:

dyn_arr a = b;
if (a.error)
  // handle it...

我没有编写此文件,因此可能会有错别字,但希望您能理解。

f

这里有两个单独的问题。

第一个与操作员重载有关。正如CashCow所提到的,C ++中的重载运算符只是函数调用的语法糖。特别是,运营商并不需要return *this这仅仅是为了方便操作员链接而创建的编程约定。

现在,链接赋值运算符(a = b = c = ...)在C ++应用程序中是一个极端情况。因此,最好通过明确禁止dyn_arr的用户使用链式分配运算符来使自己更好这样您就可以自由地从操作员那里返回错误代码,就像从常规函数中返回一样:

error_t operator = (dyn_arr const & rhs) {
    void *mem = realloc(...);
    if (mem == NULL) {
        return ERR_BAD_ALLOC; // memory allocation failed
    }
    ...
    return ERR_SUCCESS; // all ok
}

然后在调用者代码中:

dyn_arr a, b;
if ((a = b) != ERR_SUCCESS) {
    // handle error
}

第二个问题与您提供的实际示例有关:

dyn_arr a = b;

此示例不会调用重载的分配运算符!相反,它的意思是“构建dyn_arr对象ab作为参数传递给构造”。因此,此行实际上调用的副本构造函数dyn_arr如果您想了解原因,请考虑效率。如果该行的语义包括调用赋值运算符,运行时系统将不得不做两件事情,因为这行的结果:构建a了一些默认状态,然后立即将其分配给摧毁国家a的状态b相反,只需做一件事-调用副本构造即可。(并导致相同的语义,假定复制构造函数和赋值运算符的任何合理实现。)

不幸的是,您正确地认识到这个问题很难解决。除了抛出异常之外,似乎没有一种真正优雅的方法来处理构造函数中的故障。如果您不能这样做,请执行以下任一操作:

  • 在构造函数中设置一个标志,并要求/建议用户事后检查它,或者
  • 要求将指向已分配内存区域的指针作为参数传递给构造函数。

有关更多详细信息,请参见如何在C ++中处理构造函数中的失败?

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

LiveConnectClient | DownloadAsync崩溃无一例外

来自分类Dev

Laravel 4崩溃无一例外

来自分类Dev

使用 FileHelperAsyncEngine 无一例外崩溃

来自分类Dev

Segue已准备好,但表演无一例外都失败

来自分类Dev

给定大量数据时,UWP App崩溃无一例外

来自分类Dev

Android Facebook登录无一例外失败,只是“对不起,出问题了”

来自分类Dev

.htaccess重写所有内容,无一例外

来自分类Dev

Wildfly Spring Arquillian-WAR的部署和部署无一例外

来自分类Dev

List.GetRange的替代品,无一例外?

来自分类Dev

禁用所有桌面通知,Windows 10上无一例外

来自分类Dev

MVC-“无法显示此页面”-IE,无一例外

来自分类Dev

<< C ++中的运算符重载错误

来自分类Dev

错误C ++运算符重载

来自分类Dev

C ++运算符“ >>”重载错误

来自分类Dev

尝试在D中进行字符串到真实的转换,无一例外

来自分类Dev

尝试在D中进行字符串到真实的转换,无一例外

来自分类Dev

C ++运算符重载++

来自分类Dev

C ++-重载[]运算符

来自分类Dev

C ++运算符重载

来自分类Dev

C ++“ *”运算符重载

来自分类Dev

C ++运算符>>重载

来自分类Dev

()运算符重载c ++

来自分类Dev

C ++运算符重载[]

来自分类Dev

C ++运算符重载?

来自分类Dev

C ++运算符重载

来自分类Dev

C ++:运算符重载:类内和类外。与预递增运算符的歧义

来自分类Dev

如何在C#中重载一元运算符=。它给错误

来自分类Dev

如何在C#中重载一元运算符=。它给了错误

来自分类Dev

尝试重载模板类中的/运算符的C ++错误