【问题标题】:RAII classes with transient resources具有瞬态资源的 RAII 类
【发布时间】:2018-11-04 20:25:23
【问题描述】:

我对许多现代 C++/OOP 概念还很陌生,我有一个关于 RAII 设计的问题。

考虑一个管理和接口瞬态资源的类:TCP 套接字连接、到蓝牙设备的连接以及与所述设备的通信。诸如此类的事情。如果资源不可用或变得不可用,我们可以假设该类完全无用。

我无法确定 RAII(具体而言,获取/连接到 ctor 中的资源)对于此类类是好还是坏。

一方面,如果类功能依赖于资源,那么从 ctor 抛出而不是稍后调用 Connect() 似乎是有意义的。另一方面,获取瞬态资源通常涉及一些阻塞和/或异步操作,这对我来说是糟糕的构造函数设计。

我发现了一些围绕这个问题的其他主题,但还没有完全满足我的好奇心: RAII, Berkeley Sockets, and STL Containers

RAII for resources that can be invalidated

我们将不胜感激任何关于最佳实践的指导!

编辑:根据下面的 cmets 澄清我的问题。 RAII 中处理建立所有类不变量的构造函数的部分——设备连接是一个不变量,因为类应该保证所有试图与该设备通信的公共方法在构造后都是有效的。但是——由于程序无法控制远程设备的可用性,这实际上可以被认为是类不变量吗?

【问题讨论】:

  • 我对 C++ 中 RAII 的理解是它不应该强迫你在构造函数中获取资源。 AFAIK,没有std:: 类要求。您可以拥有一个“空”向量、线程、文件流、智能指针等(通常是特定类的默认构造实例)。 RAII 更多的是关于在析构函数中自动释放资源。请注意,即使那样,资源通常也可以在某些成员函数(例如,std::fstream::close)销毁之前手动释放。这可以让您更好地控制错误,因为抛出析构函数是邪恶的。
  • RAII 是一个指南。当它有意义时,完全接受它。如果没有,请保留其范围绑定的资源管理部分。
  • 感谢两位的意见! Daniel——我认为 RAII 的一个组成部分是在构造函数中建立和初始化类不变量。我想我的问题是“可以将瞬态资源视为类不变量吗?”再加上“在 ctor evil 中是否存在阻塞连接?”

标签: c++ oop c++11 raii


【解决方案1】:

如果资源可以具有“空”状态,那么拥有该资源的类拥有默认构造函数(以及acquirerelease 方法)是完全合理的。

所有必须检查非空的成员表示类不能有用地具有“空”状态,它不应该是DefaultConstructable,而应该只是@987654322 @如果是Copyable

通常你会有一个acquired的构造函数。

可以异步构造一些东西,尽管这将涉及将构造包装在异步函数中。

template <typename T, typename ... Args>
std::future<T> constructAsync(Args&& args...)
{
    return std::async([](Args&& args...) { return T(std::forward<Args>(args)...); }, std::forward<Args>(args)...);
}

int main()
{
    auto foo = constructAsync<Foo>();
    auto bar = constructAsync<Bar>("some", "params");

    foo.get().frob(bar.get()); // only occurs when both are ready
}

【讨论】:

  • 这不是稍微削弱了 RAII 的一大优势吗? RAII 模式的优点之一是避免需要获取/释放,然后在其他成员函数中删除所有实现逻辑,以检查是否已调用获取/释放。不过,如果没有办法解决它,就是这样。
  • @SeanKelly 添加了一些解释:并非所有资源都处于“空”状态,这严重限制了您可以使用 RAII 包装器执行的操作。
  • 这一切都是有道理的,但是在构建时获得但后来(通过外部手段)失效的资源的想法对我来说听起来像是一个不同的话题。除非我错过了什么。
  • @SeanKelly 经典是搬离价值。以前的所有者释放给新的所有者,并且可以在不影响资源的情况下销毁
  • 哦,我明白你的意思了。当然-我不太担心破坏在我的情况下“消失”的资源。这更像是一个哲学问题:鉴于 RAII 为消费者提供了在构造 RAII 对象后获取、可用和初始化其资源的保证,作为成员具有移动值(例如)是否违反 RAII 的精神RAII 类的变量?或者这样做可以吗?
猜你喜欢
  • 1970-01-01
  • 2013-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-29
  • 2014-07-06
  • 2011-01-29
相关资源
最近更新 更多