【问题标题】:What does holding a resource is a class invariante mean in RAII?在 RAII 中,持有资源是类不变量意味着什么?
【发布时间】:2017-02-21 03:29:22
【问题描述】:

在 RAII 中,持有资源是类不变量是什么意思?

RAII's Wikipedia page 上确实声明:

在 RAII 中,持有资源是类不变量,并且与对象生命周期相关联:资源分配(获取)在对象创建(特别是初始化)期间由构造函数完成,而资源释放(释放)在对象期间完成由析构函数销毁(特别是最终化)。

D language 为例,我们可以很容易地理解Class Invariant 的含义:

class Date {
  int day;
  int hour;

  invariant() {
    assert(1 <= day && day <= 31);
    assert(0 <= hour && hour < 24);
  }
}

它是一个约束,指的是类字段可以保持什么才能被视为有效状态。然而,持有资源意味着什么?是不是意味着资源是我的,从constructor的constructor一直到destructor的销毁都是我的?

【问题讨论】:

标签: c++ raii invariants


【解决方案1】:

这是否意味着资源是我的,并且从构造函数的构造到被解构函数销毁为止都是我的

在正确设计的程序中就是这种情况,但所有权的概念在 C++ 中并未强制执行。

很容易“射中自己的脚”并将资源提供给其他对象。例如,当资源是指针时,您可能会不小心在对象之间共享它,如下所示:

struct A
{
    int some_variable;
};

struct A_holder
{
    A* ptr;
    A_holder()
    {
        ptr = new A();
    }
    ~A_holder()
    {
        delete ptr;
    }
};

int main()
{

    {
        A_holder a_holder;
        auto another_A_holder = a_holder;
    }
   //error because delete is called twice:
   //first on A_holder's pointer and a second time on another_A_holder's pointer
    return 0;
}

零规则见https://rmf.io/cxx11/rule-of-zero

【讨论】:

  • 值得添加 deleteing 复制构造函数和赋值运算符作为对此的简单防御
  • @user4581301 是的,我最喜欢的方式是从 boost::noncopyable 继承
  • 如果您关注rule of five / rule of zero,则可以强制执行。将ptr 更改为unique_ptr,将解决问题。
  • @BryanChen 是的,但这与要求它的语言不同。想想 rust 中的“借用”。
  • @addons_zz 当你编写一个非常特殊和稀有的类直接保留资源时,你应该只使用 3/5 规则。对于大多数程序来说,这种类已经在 std::vector. 之类的东西中实现了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-11
相关资源
最近更新 更多