jjzjj

C++ 运算符重载错误检查无异常

coder 2024-02-18 原文

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

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

尽管无一异常(exception),以一种明智的方式将错误的分配错误通知调用者,同时仍然保持强大的错误安全性变得相当具有挑战性。我可以有一个类的错误属性,调用者必须在每次涉及动态分配的调用后检查它,但这似乎不是一个最佳解决方案。

编辑:

这是我目前得到的最好的想法(在上一段中被突出显示为一个不太理想的解决方案),任何改进将不胜感激:

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...

我还没有编译这个,所以可能会有拼写错误,但希望你明白了。

最佳答案

这里有两个不同的问题。

第一个与运算符重载有关。正如 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 对象 a 并将 b 作为构造函数的参数”。所以这一行实际上调用了dyn_arr的拷贝构造函数.如果您有兴趣了解原因,请从效率的角度考虑。如果该行的语义包括调用赋值运算符,运行时系统将作为该行的结果做两件事:构造a。具有一些默认状态,然后通过分配给 a 立即销毁该状态b的状态| .相反,只做一件事——调用复制构造——就足够了。 (并导致相同的语义,假设复制构造函数和赋值运算符的任何合理实现。)

不幸的是,您认识到这个问题很难处理是正确的。除了抛出异常之外,似乎没有真正优雅的方法来处理构造函数中的失败。如果你不能这样做,要么:

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

有关详细信息,请参阅 How to handle failure in constructor in C++?

关于C++ 运算符重载错误检查无异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25444357/

有关C++ 运算符重载错误检查无异常的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  5. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  6. ruby - 触发器 ruby​​ 中 3 点范围运算符和 2 点范围运算符的区别 - 2

    请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是

  7. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  8. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  9. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  10. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

随机推荐