【问题标题】:What is the exception safety guarantee for getter (by value) methods?getter(按值)方法的异常安全保证是什么?
【发布时间】:2015-09-24 10:28:58
【问题描述】:

对于以下示例类,getter 方法的exception safety 保证是什么?

这种 getter 方法是否提供了最低限度的强保证?

按值返回基本类型是否总是提供不抛出保证?

class Foo
{
public:

    // TODO: Constructor

    // Getter methods
    int getA() const { return a; }
    std::string getB() const { return b; }
    std::vector<int> getC() const { return c; }
    Bar getD() const { return d; }
    std::vector<Bar> getE() const { return e; }

protected:
    int a;
    std::string b;
    std::vector<int> c;
    Bar d;
    std::vector<Bar> e;
}

【问题讨论】:

    标签: c++ exception exception-safety


    【解决方案1】:

    根本无法保证异常安全。

    例如,如果 a 未初始化,getA() 可能会抛出异常(或为此做任何其他事情,因为行为未定义)。如果读取了未初始化的变量,某些芯片(例如 Itanium)会发出信号。

    如果内存不足,getC() 可能会抛出 std::bad_allocgetB()getD()getE() 同上。

    【讨论】:

    • 即使 getB 为 no,但它可能会抛出 bad_alloc。仅供参考
    • 我理解你对getA() 所说的话——永远不要抛出我需要确保构造函数(包括复制和移动)始终初始化a。但是,如果任何 getter 抛出异常,由于类的状态没有被修改,这不会被归类为强保证吗?
    【解决方案2】:

    我认为您的所有操作都满足强异常安全性,前提是(如果相关)Bar(const Bar&amp;) 复制构造函数是强安全的。此外,getA 将满足 nothrow 保证,前提是 a 已初始化,例如在构造函数中。

    Foo 的任何部分都不会被这些 const 方法修改,因此主要关注的是新创建的 vectors 的泄漏 - 如果从 @987654328 复制成员时出现异常,这些应该自动释放@ 或 e 为返回值。

    a 必须正确初始化的原因是复制未初始化的数据可能会在诸如 Itanium 之类的架构上抛出,如Bathsheba's answer 中所述。

    【讨论】:

      猜你喜欢
      • 2013-11-01
      • 2019-06-21
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-02
      相关资源
      最近更新 更多