问题标签 [raii]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
1948 浏览

ruby - Ruby 中的 RAII(或者,如何在 Ruby 中管理资源)

我知道这是设计使然,您无法控制对象被销毁时会发生什么。我也知道将一些类方法定义为终结器。

但是,C++ 的 RAII 的 ruby​​ 习语是(资源在构造函数中初始化,在析构函数中关闭)吗?即使发生错误或异常,人们如何管理对象内部使用的资源?

使用确保工作:

但是该类的用户必须记住每次需要调用 open 方法时 都要执行整个 begin-rescue-ensure chacha 。

例如,我将有以下课程:

如果异常是由其他类引起的并且脚本退出,则不会关闭 resource_handle。

还是更多的问题是我仍然在做这件事太像 C++?

0 投票
4 回答
9244 浏览

c++ - CUDA:在 C++ 中包装设备内存分配

我现在开始使用 CUDA,不得不承认我对 C API 有点失望。我理解选择 C ​​的原因,但是如果该语言是基于 C++ 的,那么有几个方面会简单得多,例如设备内存分配(通过cudaMalloc)。

我的计划是自己做这件事,使用operator new放置new和 RAII 重载(两种选择)。我想知道到目前为止是否有任何我没有注意到的警告。该代码似乎有效,但我仍然想知道潜在的内存泄漏。

RAII代码的用法如下:

在这种情况下,一个类可能是矫枉过正(特别是因为你仍然必须使用cudaMemcpy,类只封装 RAII)所以另一种方法是放置new

在这里,cudaDevice仅仅作为一个标签来触发过载。然而,由于在正常放置中new这将指示放置,我发现语法奇怪地一致,甚至可能比使用类更可取。

我会很感激各种批评。是否有人可能知道下一个版本的 CUDA 是否计划在这个方向上做一些事情(正如我所听说的,这将改进其对 C++ 的支持,无论他们的意思是什么)。

所以,我的问题实际上是三个方面:

  1. 我的展示位置new重载在语义上是否正确?它会泄漏内存吗?
  2. 有没有人知道未来 CUDA 发展朝着这个大方向发展的信息(让我们面对现实:C++ s*ck 中的 C 接口)?
  3. 我怎样才能以一致的方式更进一步(还有其他 API 需要考虑,例如不仅有设备内存,还有常量内存存储和纹理内存)?

关于这里使用的单身人士:是的,我知道它的缺点。但是,这些在这种情况下无关紧要。我在这里只需要一个不可复制的小型标签。其他一切(即多线程注意事项、初始化时间)都不适用。

0 投票
6 回答
2460 浏览

c++ - shared_ptr:它是做什么用的

我在我的代码中大量使用了 boost::scoped_ptr,它很棒,但我目前正在使用到处使用 shared_ptr 的软件,我想知道我是否遗漏了一些东西。

AFAIK shared_ptr 仅在不同的线程要访问相同的数据并且您不知道线程将要完成的顺序时才有用(shared_ptr 确保对象存在直到最后一个线程完成它)。

还有其他用例吗?

0 投票
10 回答
17097 浏览

c - 在纯 C 中实现 RAII?

是否可以在纯 C中实现RAII ?

我认为以任何理智的方式都是不可能的,但也许可以使用某种肮脏的技巧。free想到重载标准函数,或者可能会覆盖堆栈上的返回地址,以便当函数返回时,它会调用其他一些以某种方式释放资源的函数?或者也许有一些 setjmp/longjmp 技巧?

这纯粹是学术兴趣,我无意实际编写如此不可移植和疯狂的代码,但我想知道这是否可能。

0 投票
6 回答
1964 浏览

c++ - 是否存在“最终”构造在 C++ 中有用的情况?

Bjarne Stroustrup 在他的C++ Style and Technique FAQ中写道,强调我的:

因为 C++ 支持几乎总是更好的替代方案:“资源获取即初始化”技术(TC++PL3 第 14.4 节)。基本思想是用一个本地对象来表示一个资源,这样本地对象的析构函数就会释放资源。这样,程序员就不会忘记释放资源。例如:

在一个系统中,我们需要为每个资源创建一个“资源句柄”类。但是,我们不必为每次获取资源都有一个“finally”子句。在现实系统中,资源获取远多于资源种类,因此“资源获取即初始化”技术导致的代码比使用“finally”构造更少。

请注意,Bjarne 写的是“几乎总是更好”而不是“总是更好”。现在我的问题是:在什么情况下finally构造比在 C++ 中使用替代构造 (RAII) 更好?

0 投票
6 回答
61618 浏览

c++ - C++ 中的 RAII 和智能指针

在 C++ 的实践中,什么是RAII,什么是智能指针,这些是如何在程序中实现的,以及将 RAII 与智能指针一起使用有什么好处?

0 投票
9 回答
2043 浏览

c++ - 关于智能指针及其不可避免的不确定性的问题

在过去的两年里,我一直在我的项目中广泛使用智能指针(确切地说是 boost::shared_ptr)。我理解并欣赏他们的好处,而且我通常非常喜欢他们。但是我使用它们的次数越多,我就越想念 C++ 在内存管理和 RAII 方面的确定性行为,而我在编程语言中似乎喜欢这种行为。智能指针简化了内存管理过程并提供了自动垃圾收集等功能,但问题在于,通常使用自动垃圾收集,而智能指针具体会在(去)初始化的顺序上引入某种程度的不确定性。这种不确定性剥夺了程序员的控制权,正如我最近意识到的那样,设计和开发 API 的工作,

为了详细说明,我目前正在开发一个 API。此 API 的某些部分要求某些对象在其他对象之前初始化或在其他对象之后销毁。换句话说,(去)初始化的顺序有时很重要。举一个简单的例子,假设我们有一个名为 System 的类。系统提供了一些基本功能(在我们的示例中为日志记录),并通过智能指针保存了许多子系统。

正如您已经知道的那样,子系统仅在系统的上下文中才有意义。但是这种设计中的子系统很容易比其父系统寿命更长。

如果我们使用原始指针来保存子系统,那么当我们的系统出现故障时,我们就会破坏子系统,当然,pSomeSubsystem 将是一个悬空指针。

虽然保护客户端程序员免受自己的伤害不是 API 设计人员的工作,但让 API 易于正确使用和难以错误使用是一个好主意。所以我问你们。你怎么看?我应该如何缓解这个问题?你会如何设计这样一个系统?

在此先感谢,乔希

0 投票
9 回答
1170 浏览

c++ - 好的或坏的 C++ 成语 - 纯粹用于构造函数/析构函数的对象?

我有一些类除了在它们的构造函数/析构函数中什么都不做。这是一个例子

我有点担心未来的可读性。我在这里是不是太“狡猾”了,变量(“忙”)从未在代码中实际使用过?一些静态分析工具是否可以建议将它们删除,或者这个习语是否足够普遍不用担心?

0 投票
3 回答
745 浏览

c# - 在 C# 中复制 C++ 的 RAII

我正在滚动我自己的记录器类,并希望在应用程序经历不同阶段时表示日志的层次结构:

等等

在 C++ 中(是的,我知道),我会使用 RAII 类,它们在创建时将自身推入日志堆栈,并在它们离开范围时弹出。然后,您可以在任何时候离开函数,并且仍然具有一致的日志记录。

显然,在 C# 中,任何变量都必须是新的,因此在下一个垃圾回收周期之前它不会被删除,如果您立即创建一个新的 classlet,您可能会有一个不同步的记录器。

人们将如何尝试在 C# 中解决这个问题?我希望记录器语法对当前函数尽可能不显眼,并且仍然支持具有多个退出点的函数。

我能想到的唯一解决方案是 closeHeirarchy() 调用每个 return 语句 - 你知道我会在某个地方错过一个。


编辑:我应该明确表示我主要对如何在 c# 中复制 RAII 行为感兴趣。是否有提供相同行为的机制?

0 投票
4 回答
13054 浏览

java - Java 是否支持 RAII/确定性破坏?

自从我使用 Java 以来已经至少 5 年了,那时,任何时候你想分配一个需要清理的对象(例如套接字、DB 句柄),你必须记住添加一个finally块并调用 cleanup 方法那里。

相比之下,在 C++(或其他对象生命周期是确定性的语言,例如 Perl)中,类实现者将定义一个析构函数,该函数在该类的对象超出范围时执行清理。这种方法的优点是对象的用户不会忘记清理它——析构函数会自动调用,即使抛出异常也是如此。这种方法采用了相当糟糕的 RAII 名称——“资源获取即初始化”。

根据我的经验,“以 RAII 方式”做事为我节省了很多精神开销,因为我不必担心是否以及何时发生资源释放。我们正在考虑将 Java 用于一个中型项目,我想知道自从我上次查看 Java 以来添加到该语言的许多新特性中是否存在某种确定性破坏。(我希望我的抱怨“Java 没有 RAII”在这个线程上受到指责,但到目前为止,我无法通过谷歌搜索找到任何细节。)

因此,如果有人可以向我指出一些关于如何在 Java 中进行此操作的介绍性材料,那就太好了!