C++ shared_ptr 和互斥量

C++ shared_ptr and mutex

我是 C++ 的新手,我必须遵循以下场景:

main.cpp

#include "Foo.h"
#include "Bar.h"

int main() {
    Bar bar{};
    auto bar_ptr = std::make_shared<Bar>(bar);

    for (int i = 0; i < 10; i++) {
        Foo foo{bar_ptr};
    }

    return 0;
}

我想要 Class Foo 的 10 个实例共享 Class Bar 的 1 个实例。 Class Foo 的每个实例都将 运行 在一个单独的线程中。我希望 Class Bar 的共享实例一次只能由一个 Foo 实例访问。这就是为什么我想给 Foo 添加一个 std::mutex。这似乎与 std::mutex 不是 copyable/moveable 相冲突。使用带 shared_ptr 的互斥锁的正确方法是什么?

Foo.h

#include <memory>
#include <utility>
#include "Bar.h"

class Foo {
    std::shared_ptr<Bar> bar_ptr;

public:
    explicit Foo(std::shared_ptr<Bar> bar_ptr){
        this->bar_ptr = std::move(bar_ptr);
    }
};

Bar.h

#include <mutex>

class Bar {
    std::mutex mutex{};

};

std::mutex是move-only类型,不能复制

在您的主函数中,您正在创建一个 Bar,然后尝试通过复制 Bar.

的实例来创建一个 std::shared_ptr

相反,只需使用 std::make_shared<Bar>() 创建一个带有默认构造函数的 shared_ptr 柱。

#include "Foo.h"
#include "Bar.h"

int main() {
    auto bar_ptr = std::make_shared<Bar>();

    for (int i = 0; i < 10; i++) {
        Foo foo{bar_ptr};
    }

    return 0;
}

为了澄清,传递给 make_shared 的参数被转发给 class 的构造函数。如果您传递 Bar& 它将尝试使用复制构造函数。

如果您不传递任何内容,它将使用默认构造函数。

如果 Bar 的构造函数在您的 use-case 中接受参数,将参数传递给 make_shared

#include <memory>
#include <utility>
#include <mutex>

class Bar {
    public:
    Bar(int i) : value(i) {}
    private:
    std::mutex mutex{};
    int value;
};

class Foo {
    std::shared_ptr<Bar> bar_ptr;

public:
    // Use the initializer list when possible
    // Otherwise we first default-construct then assign
    explicit Foo(std::shared_ptr<Bar> ptr) : bar_ptr(std::move(ptr)) {}
};

int main() {
    auto bar_ptr = std::make_shared<Bar>(5);

    for (int i = 0; i < 10; i++) {
        Foo foo{bar_ptr};
    }

    return 0;
}