基于堆栈的 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++ 范围后才能运行? 的相关文章

  • InvalidOperationException - 对象当前正在其他地方使用 - 红十字

    我有一个 C 桌面应用程序 其中我连续创建的一个线程从源 实际上是一台数码相机 获取图像并将其放在 GUI 中的面板 panel Image img 上 这必须是另一个线程 如它是控件的代码隐藏 该应用程序可以工作 但在某些机器上 我会在随
  • 用于代数简化和求解的 C# 库 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 网络上有很多代数求解器和简化器 例如 algebra com 上不错的代数求解器和简化器 然而 我正在
  • 每个托管线程是否都有自己对应的本机线程?

    我想知道是否在 Net 中创建托管线程 通过调用Thread Start 导致在后台创建一个本机线程 那么托管线程是否有对应的本机线程呢 如果是 当托管线程等待或睡眠时 是否意味着相应的本机线程也在等待或睡眠 是的 NET 线程映射到所有当
  • 复制 std::function 的成本有多高?

    While std function是可移动的 但在某些情况下不可能或不方便 复制它会受到重大处罚吗 它是否可能取决于捕获变量的大小 如果它是使用 lambda 表达式创建的 它依赖于实现吗 std function通常被实现为值语义 小缓
  • 错误:表达式不产生值

    我尝试将以下 C 代码转换为 VB NET 但在编译代码时出现 表达式不产生值 错误 C Code return Fluently Configure Mappings m gt m FluentMappings AddFromAssemb
  • 使用 Newtonsoft 和 C# 反序列化嵌套 JSON

    我正在尝试解析来自 Rest API 的 Json 响应 我可以获得很好的响应并创建了一些类模型 我正在使用 Newtonsoft 的 Json Net 我的响应中不断收到空值 并且不确定我的模型设置是否正确或缺少某些内容 例如 我想要获取
  • 单个对象的 Monogame XNA 变换矩阵?

    我读过一些解释 XNA Monogame 变换矩阵的教程 问题是这些矩阵应用于 SpriteBatch Begin matrix 这意味着所有 Draw 代码都将被转换 如何将变换矩阵应用于单个可绘制对象 就我而言 我想转换滚动背景 使其自
  • 如何区分用户点击链接和页面自动重定向?

    拥有 C WebBrowser control http msdn microsoft com en us library system windows forms webbrowser aspx在我的 WinForms 应用程序中 并意识
  • java.io.Serialized 在 C/C++ 中的等价物是什么?

    C C 的等价物是什么java io Serialized https docs oracle com javase 7 docs api java io Serializable html 有对序列化库的引用 用 C 序列化数据结构 ht
  • 如何使用 LINQ2SQL 连接两个不同上下文的表?

    我的应用程序中有 2 个数据上下文 不同的数据库 并且需要能够通过上下文 B 中的表的右连接来查询上下文 A 中的表 我该如何在 LINQ2SQL 中执行此操作 Why 我们正在使用 SaaS 产品来跟踪我们的时间 项目等 并希望向该产品发
  • 将 Word 文档另存为图像

    我正在使用下面的代码将 Word 文档转换为图像文件 但是图片显得太大 内容不适合 有没有办法渲染图片或将图片保存到合适的尺寸 private void btnConvert Click object sender EventArgs e
  • 是否有实用的理由使用“if (0 == p)”而不是“if (!p)”?

    我倾向于使用逻辑非运算符来编写 if 语句 if p some code 我周围的一些人倾向于使用显式比较 因此代码如下所示 if FOO p some code 其中 FOO 是其中之一false FALSE 0 0 0 NULL etc
  • 从 Linux 内核模块中调用用户空间函数

    我正在编写一个简单的 Linux 字符设备驱动程序 以通过 I O 端口将数据输出到硬件 我有一个执行浮点运算的函数来计算硬件的正确输出 不幸的是 这意味着我需要将此函数保留在用户空间中 因为 Linux 内核不能很好地处理浮点运算 这是设
  • 在一个平台上,对于所有数据类型,所有数据指针的大小是否相同? [复制]

    这个问题在这里已经有答案了 Are char int long 甚至long long 大小相同 在给定平台上 不能保证它们的大小相同 尽管在我有使用经验的平台上它们通常是相同的 C 2011 在线草稿 http www open std
  • 如何在 32 位或 64 位配置中以编程方式运行任何 CPU .NET 可执行文件?

    我有一个可在 32 位和 64 位处理器上运行的 C 应用程序 我试图枚举给定系统上所有进程的模块 当尝试从 64 位应用程序枚举 32 位进程模块时 这会出现问题 Windows 或 NET 禁止它 我认为如果我可以从应用程序内部重新启动
  • AES 128 CBC 蒙特卡罗测试

    我正在 AES 128 CBC 上执行 MCT 如中所述http csrc nist gov groups STM cavp documents aes AESAVS pdf http csrc nist gov groups STM ca
  • Cmake 链接共享库:包含库中的头文件时“没有这样的文件或目录”

    我正在学习使用 CMake 构建库 构建库的代码结构如下 include Test hpp ITest hpp interface src Test cpp ITest cpp 在 CMakeLists txt 中 我用来构建库的句子是 f
  • 如何在非控制台应用程序中查看 cout 输出?

    输出到调试窗口似乎相当繁琐 我在哪里可以找到cout如果我正在编写非控制台信息 则输出 Like double i a b cout lt lt b lt lt endl I want to check out whether b is z
  • C++ 函数重载类似转换

    我收到一个错误 指出两个重载具有相似的转换 我尝试了太多的事情 但没有任何帮助 这是那段代码 CString GetInput int numberOfInput BOOL clearBuffer FALSE UINT timeout IN
  • 方法优化 - C#

    我开发了一种方法 允许我通过参数传入表 字符串 列数组 字符串 和值数组 对象 然后使用这些参数创建参数化查询 虽然它工作得很好 但代码的长度以及多个 for 循环散发出一种代码味道 特别是我觉得我用来在列和值之间插入逗号的方法可以用不同的

随机推荐

  • 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