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;
}
我是 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;
}