基于栈的RAII是否保证只有在C ++范围之外才能运行? [英] Are stack based RAII guaranteed to be run only after going out of scope in C++?

查看:128
本文介绍了基于栈的RAII是否保证只有在C ++范围之外才能运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++中使用资源获取初始化(RIAA)时,通常会有以下内容:

When using Resource Acquisition Is Initialisation (RIAA) in C++ it's typical to have something the following:

class CriticalSection {
public:
    void enter();
    void leave();
};

class SectionLocker {
public:
    SectionLocker(CriticalSection& cs)
    : mCs(cs) {
       cs.enter();   
    }

    ~SectionLocker() {
        cs.leave();
    }

private:
    CriticalSection& mCs;
};

CriticalSection gOperationLock; // Global lock for some shared resource

void doThings(int a, int b) {
    SectionLocker locker(gOperationLock);
    int c = doOtherThings(a);
    doMoreThings(b);
    doOneMoreThing(a, b, c);
}



我知道在一些垃圾收集语言(如CLR)为什么这是不安全的许多原因是doThings()内的locker对象将有资格在doThings()返回之前进行垃圾收集,因为locker在创建后从未被引用。

I know that in some garbage collected languages (such as the CLR) that one of the many reasons why this would be unsafe is that the locker object inside doThings() would be eligible for garbage collection before doThings() returns, as locker is never referenced after being created.

是否只有在调用doOneMoreThing()之后调用locker的析构函数,并且在C ++中定义良好的行为才是预期的行为?

Is the expected behaviour, of the destructor for locker only being called after the call to doOneMoreThing(), well defined behaviour in C++?

如果是这样,是否有任何保证,当析构函数被调用(和gOperationLock被释放)?

If so, are there any guarantees about when the destructor will be called (and gOperationLock is released)? Or is it just at some point after it goes out of scope?

推荐答案

C ++标准(n3290)在这个版本中很清楚。您的RAII对象总是会有自动存储持续时间(如果他们不是你错了!)

The C++ standard (n3290) is pretty clear on this. Your RAII objects are always going to have automatic storage duration (if they don't you're doing it wrong!) so

§12.4.11说:


对于构造的对象,析构函数被隐式调用
自动存储持续时间(3.7.3) object
is created(6.7)

"Destructors are invoked implicitly .... for constructed objects with automatic storage duration (3.7.3) when the block in which an object is created exits (6.7)"

§6.7.2说:


在块中声明的具有自动存储持续时间的变量是
,从块中退出(6.6)

Variables with automatic storage duration declared in the block are destroyed on exit from the block (6.6)

和§6.6.2说明:


退出范围自动
在此范围内构建的存储持续时间(3.7.3)是按照其构造的相反顺序销毁的

On exit from a scope (however accomplished), objects with automatic storage duration (3.7.3) that have been constructed in that scope are destroyed in the reverse order of their construction.

这里一起阅读,毫无疑问,实现这一点的唯一符合的方法是可观察的行为是自动存储对象在块结束时被销毁。

Which read together leaves no doubt that the only conforming way to implement this is for the observable behaviour to be that automatic storage objects are destructed at the end of a block.

这篇关于基于栈的RAII是否保证只有在C ++范围之外才能运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆