首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何应对RAII的资源等待

如何应对RAII的资源等待
EN

Stack Overflow用户
提问于 2019-12-29 13:41:49
回答 2查看 217关注 0票数 0

我刚接触过C++,目前正在学习RAII (资源获取是初始化)模式。我很好奇如何处理他们需要等待的资源。

在Java中,可能要做的事情是:

代码语言:javascript
复制
MyClass obj = new MyClass();
new Thread(
    () -> obj.initialize(); // resource acquisition
).start()

...

if (obj.initialized()) {
    // Use object
}

换句话说,我们可以在后台进行时间密集型的资源获取.

我们如何在C++和RAII中做到这一点?或者这是RAII的限制?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-12-29 16:46:57

RAII意味着资源由某个对象定义。理想情况下,该对象的构造函数获取资源,析构函数释放它。在对象有效的时间内,可以使用对象与资源进行交互。

如果一个资源“需要等待”,那么根据RAII的规则,这意味着您还没有一个表示该资源的对象。相反,您有一个表示将来可用的资源的对象。

这就是为什么C++称这种类型为std::future。它是一个模板,参数是正在等待创建的对象的类型。

从概念上讲,future只是将对象(或异常)从生成它(可能是异步)的代码块转发给接收方的一种方式。

现在给出您的示例,我们需要从initialize中删除MyClass,并使之成为一个返回MyClass实例的函数。它可以是MyClass的静态成员,也可以是名称空间范围内的函数。

所以代码本质上是这样的:

代码语言:javascript
复制
auto future = std::async(initialize);

...

if(future.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
  MyClass resource = future.get(); //The `future` is now empty. Any exceptions will be thrown here.

  //use resource
}
票数 3
EN

Stack Overflow用户

发布于 2019-12-29 15:52:40

当可能获得一个尚未准备好使用的对象时,RAII解决反模式问题。尤其是,您的Java代码有相同的反模式-- MyClass的用户很容易在构造对象之后忘记运行initialize方法。

当需要进行复杂初始化时,执行RAII的最简单方法是通过工厂方法。将可能不安全的构造函数设置为私有,并公开将为您构造和初始化对象的公共静态函数。特别是,如果您想同时运行初始化,没有什么可以阻止您将该工厂方法的返回类型转换为std::future或类似的方法。

关键是RAII的目的--不可能获得未初始化的资源。通过创建获取始终初始化资源的函数的唯一方法,您将获得RAII。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59519943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档