基于堆栈的 RAII 是否保证仅在超出 C++ 范围后才能运行?

2024-01-12

使用时资源获取即初始化 (RIAA) http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization在 C++ 中,通常有以下内容:

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() 返回之前 doThings() 内的 Locker 对象将有资格进行垃圾收集,因为 Locker 永远不会创建后引用。

仅在调用 doOneMoreThing() 之后调用 Locker 析构函数的预期行为是否是 C++ 中定义良好的行为?

如果是这样,是否可以保证何时调用析构函数(并且释放 gOperationLock)?或者只是在超出范围后的某个时刻?


C++ 标准 (n3290) 对此非常清楚。您的 RAII 对象始终会具有自动存储持续时间(如果没有,您就做错了!)

§12.4.11 说:

“对于构造对象,隐式调用析构函数...... 自动存储持续时间(3.7.3)当对象所在的块 创建退出 (6.7)"

§6.7.2 说:

块中声明的具有自动存储期限的变量是 退出区块时被销毁 (6.6)

§6.6.2 规定:

在退出作用域时(无论如何完成),具有自动功能的对象 在该范围内构建的存储持续时间(3.7.3)是 以与建造相反的顺序被摧毁。

毫无疑问,实现这一点的唯一一致方法是可观察的行为是自动存储对象在块末尾被破坏。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于堆栈的 RAII 是否保证仅在超出 C++ 范围后才能运行? 的相关文章

  • 将 void *user_data 转换为对象

    我该如何投射void something到标准 C 中的对象 具体来说我想投void userdata to std map
  • 当我使用 SetWindowsHookEx WH_KEYBOARD_LL 交换按键时,为什么我的程序会陷入过多键盘输入事件的循环?

    I am trying to write a program for Windows system that swaps the A and B keys i e when I press the A key B gets typed an
  • std::tr1::function 和 std::tr1::bind

    我在使用时遇到问题veryC 类中的复杂 C 函数 重写 C 函数是not一个选项 C函数 typedef void integrand unsigned ndim const double x void fdata unsigned fd
  • boost::asio::io_service 是否保留处理程序的顺序?

    Does boost asio io service http www boost org doc libs release doc html boost asio reference io service html保证处理程序的调用顺序与
  • 修剪 UIImage 边框

    这是我想要修剪的图像的示例 我想去掉图像周围的边框 在本例中是顶部和底部的黑条 我在Github上找到了一个库 CKImageAdditions https github com cmkilger CKImageAdditions 但是它似
  • 为什么我不能从对中返回 unique_ptr?

    为什么我不能从对中返回 unique ptr include
  • 函数指针上的未知类型 F TYPE

    include
  • 修改正在运行的可执行文件的资源内容

    All 我将应用程序设置存储在资源中 当我的程序首次加载时 我使用 WinAPI 读取指定的资源 然后我解析检索到的字节数据 这对我来说完美无缺 现在假设用户更改了我的应用程序中的设置 他 她检查复选框控件 我想将更新的设置保存到我的资源中
  • 我可以在 C++ 中重写非虚函数吗

    我想知道我可以重写 C 中的非虚函数吗 因为我在使用 C 时发现了这个问题override关键字我的代码如下 class A public void say cout lt lt From A n class B public A publ
  • 除空字符串外的任何内容的正则表达式

    是否可以使用正则表达式来检测任何不是 空字符串 的内容 如下所示 string s1 string s2 string s3 string s4 etc 我知道我可以使用修剪等 但我想使用正则表达式 s 将匹配任何包含至少一个非空格字符的字
  • 如何使用 ProtoGen 从 proto 文件生成结构

    我们一直在使用 protobuf net ProtoGen 从 proto 文件生成 C cs 文件 我们希望代替类来生成结构 例如 DataContract public struct Entity1 ProtoMember 1 publ
  • 将授权标头添加到 Web 参考

    我正在尝试向客户端的网络服务发出请求 我不知道客户端的底层平台 我使用 添加 Web 引用 在 Visual Studio 2010 中使用了客户端的 WSDL 并生成了我的代理类 称为 ContactService 我现在需要将如下所示的
  • 为什么我无法调试动态加载的程序集?

    我正在开发一个 Web API 项目 该项目使用内部模拟框架 允许拦截和修改来自控制器的响应 它使用 MEF 加载包含某些先决条件匹配时执行的代码的程序集 我知道这是正常工作的 因为我可以在响应中看到模拟已被执行 但由于某种原因我无法调试动
  • 如何在 Visual Studio 2010 Express 中引用 system.drawing?

    我对此有点陌生 我的印象是要绘制我创建的矩形 我需要使用 system drawing graphics 问题是 我收到错误 命名空间 System 中不存在类型或命名空间名称 drawing 您是否缺少程序集引用 当我右键单击解决方案资源
  • 生成范围 [min,max] 内的随机数 [重复]

    这个问题在这里已经有答案了 我正在使用 C 生成范围 min max 内的整数随机数 我在用 int random int int min int max return min rand max min 但我认为上面的代码适用于范围 min
  • C++ 联合数组和变量?

    在C 中没有办法做这样的事情吗 union Scalar x y Scalar v 2 Where x v 0 and y v 1 既然您使用的是 C 而不是 C 并且它们具有相同的类型 为什么不直接将 x 设为对 v 0 的引用 将 y
  • LinkedBlockingQueue 抛出 InterruptedException

    我有这段代码 ALinkedBlockingQueue应该只抛出一个Exception如果在等待添加到队列时被中断 但这个队列是无限的 所以它应该尽快添加 为什么我的关闭方法会抛出一个InterruptedException private
  • 替换全局热键

    我有一个位于托盘中的应用程序 我想定义多个热键来触发我的程序中的事件 我从 AaronLS 在这个问题中的出色回答中找到了灵感 使用C 设置全局热键 https stackoverflow com a 27309185 3064934 如果
  • DataGridView 捕获用户行选择

    我在处理选择时遇到问题DataGridView 我的网格视图包含一个金额列 表单上有一个文本框 应显示所选网格视图行的总数 因此 我需要在用户选择 取消选择 gridview 行时捕获事件并相应地计算 添加 减去 金额 我找到了两种方法 使
  • C#:如何处理乱序 TCP 数据包?

    请有人解释一下如何处理乱序数据包 我使用原始套接字来捕获数据包 并在数据包到来时解析它们 但其中一些数据包的顺序错误 例如 ID 标志 16390 PSH ACK 16535 PSH ACK 16638 确认 16640 PSH ACK 1

随机推荐

  • java.io.FileNotFoundException:(权限被拒绝)

    我想读取 Vista 上我的文档文件夹中的文件 该字段确实存在于指定位置 但在尝试打开文件的输入流时仍然收到以下错误 java io FileNotFoundException Permission denied at java io Fi
  • Angular 2嵌套路由解析执行

    例如 如果我有以下路线组织 const appRoutes Routes path component AppComponent resolve app AppResolver children path component NestedC
  • 多个线程调用同一个函数

    假设我们有多个线程都调用同一个函数 def foo do stuff end 100 times do i Thread new do foo end end 如果当前有两个或多个线程foo 它们是否共享相同的局部变量foo 这涉及到我的第
  • Android MediaPlayer 无法在运行 Android 5.1.1 的 Galaxy S6 上播放

    我发现运行 Android 5 1 1 的 Galaxy S6 特有的问题 我正在使用 MediaPlayer 播放音频流 并且在设备和 Android 版本的此特定配置上 它无法到达 onPrepared 方法 因此永远不会播放 Over
  • 如何发布具有多个选定值的 HTML 列表框的选择

    我在 HTML 表单上有一个带有 提交 按钮的列表框 列表框启用了多项选择 我可以在列表框中选择多个值 但我不知道如何确定提交表单时选择了哪些值 另外 我使用 JavaScript 动态地将用户生成的值添加到列表框中 并且我希望能够在表单提
  • 如何检测用户何时关闭 Admob 中的插页式广告?

    我最近将广告移至新版本 现在使用 com google android gms ads 但我意识到我现在缺少一些非常重要的东西 我曾经能够使用 OnDismissScreen 检测用户何时关闭插页式广告 但现在看来这不再是一个选项 我曾经做
  • 通过套接字发送图像流问题 - Android

    我已经实现了一个应用程序 它使用 SP 相机拍照并通过套接字将其发送到服务器 我使用以下代码读取本地存储的图像文件 并通过套接字以连续的块形式发送它 FileInputStream fileInputStream new FileInput
  • 仅复制并粘贴值和格式 - Google 脚本

    我想仅复制和粘贴值和格式 而不是公式 E G A1是动态文本 A1 测试 A2 A1 我想使用一个脚本 激活时它将 A2 格式和文本复制到 A3 我尝试使用 formatOnly true contentsOnly true 但它不断复制公
  • 为什么 std::swap 被移至

    Why has std swap已移至
  • 在 pgAdmin (PostgreSQL) 中查看数据的简单方法

    我已经搜索这个问题一个多小时了 没有任何线索 在 Heidi SQL 用于 MySQL 中 我只需点击几下即可打开任何表来查看其数据 但在 pgAdmin 中 我必须折叠许多子文件夹才能做到这一点 database Schemas publ
  • ComponentDidUpdate SetState ReactJS无限循环

    尽管有很多具有相同主题的问题 但我无法得到我的问题的答案 Problem 我有一个选择下拉菜单 单击该按钮后 我会调用一个 Api 来获取一些关键值 我将这组键值输入字段视为一个组件 因此 每次选择下拉菜单的 onChange 时 我都会使
  • 如何在php中使用css样式

    我使用 php 显示来自 mysql 的数据 这是我的 CSS 语句
  • 在 Node.js 7 中抑制 UnhandledPromiseRejectionWarning 的正确方法是什么?

    在 Node js 中 我有一个仅包含一个函数的模块 该函数返回 Promise 并且该 Promise 可能会被拒绝 我仍然不想强迫该模块的所有用户明确处理拒绝 在某些情况下 根据设计 忽略返回的承诺是有意义的 另外 我不想剥夺模块用户处
  • 遗传算法/遗传编程解决方案有哪些好的例子? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 验证上下文始终为 NULL?

    我有自定义验证属性 如下所示 public class MyCustomAttribute ValidationAttribute protected override ValidationResult IsValid object val
  • 有没有办法在java应用程序中完全禁用RMI?

    在我们的应用程序中 远程过程调用是通过自己的基于 netty 的命令调度程序系统来解决的 我们有很多模块 大约 20 个 我想在单独的 jvm s 中运行所有模块 我的问题是 RMI 为每个 JVM 生成大约 17 个线程 我根本不需要 R
  • TailwindCSS:禁用的变体不起作用

    我正在尝试使用disabled顺风的变体 但它似乎不起作用 我不知道该怎么办 如果按钮被禁用 我想更改按钮外观 我已阅读文档 它说默认情况下未启用 禁用 变体 所以我修改了 tailwind config js 现在它看起来像这样 modu
  • 自动拉伸垂直列(div)

    检查这个fiddle http jsfiddle net Q7MFX 2 please 我想要以下内容 红色列有一些文本 黄色是动态内容 绿色没有任何内容 只是一种颜色 我希望红色和绿色列的高度与黄色内容一样高 height 100 没用
  • 在php中生成Excel文件时显示进度条

    我有一个 HTML 表单 当您通过单击按钮提交表单时 应用程序会使用 PHPExcel 生成一个 Excel 文件 一切正常 但是当 Excel 文件很大时 等待时间会很长 我想添加进度条或显示完成值的百分比 我的问题是我不知道如何将其插入
  • 基于堆栈的 RAII 是否保证仅在超出 C++ 范围后才能运行?

    使用时资源获取即初始化 RIAA http en wikipedia org wiki Resource Acquisition Is Initialization在 C 中 通常有以下内容 class CriticalSection pu