【问题标题】:Can a critical section object be stored in a std::vector?临界区对象可以存储在 std::vector 中吗?
【发布时间】:2019-10-25 07:34:49
【问题描述】:

根据the documentation,无法复制或移动关键部分对象。

这是否意味着它不能作为实例安全地存储在 std::vector 样式集合中?

【问题讨论】:

  • 我猜这不是 C++ 类?如果是,则应明确删除其复制/移动 ctor。
  • 听起来类似于std::mutex(不可复制和不可移动),答案here 表示是的,你可以,但你不能做任何会可能会调整向量的大小(这意味着您只能以固定大小构造它)
  • 另外,unique_ptr 可能是在 std::vector 中安全地存储对这些引用的选项
  • 然而,windows api 结构通常只是声明为 POD,这意味着如果您尝试复制或移动它,您不会收到编译器错误:/
  • @BradAllred 它是 C API 的一部分

标签: winapi move stdvector critical-section


【解决方案1】:

正确; CRITICAL_SECTION 对象不应被复制/移动,因为它可能会停止工作(例如,它可能包含指向自身的指针)。

一种方法是存储智能指针向量,例如(C++17 代码):

#include <windows.h>
#include <memory>
#include <vector>

using CS_ptr = std::unique_ptr<CRITICAL_SECTION, decltype(&DeleteCriticalSection)>;

CS_ptr make_CriticalSection(void)
{
    CS_ptr p(new CRITICAL_SECTION, DeleteCriticalSection);
    InitializeCriticalSection(p.get());
    return p;
}

int main()
{
    std::vector<CS_ptr> vec;
    vec.push_back( make_CriticalSection() );    
}

考虑使用std::recursive_mutex,它是 CRITICAL SECTION 的直接替代品(并且可能只是将其包装在 Windows 实现中),并在其析构函数中执行正确的初始化和释放。

标准互斥体也是不可复制的,因此对于这种情况,如果您想要它们的向量,您可以使用 std::unique_ptr&lt;std::recursive_mutex&gt;

As discussed here 还要考虑您是否真的想要 std::mutex 而不是递归互斥锁。

注意:Windows Mutex 是一个进程间对象; std::mutex和朋友对应一个CRITICAL_SECTION


我还建议重新考虑对互斥体向量的需求;无论您尝试做什么,都可能有更好的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-01
    • 2015-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-29
    • 1970-01-01
    相关资源
    最近更新 更多