我目前正在整理一个严重依赖的应用程序,shared_ptr到目前为止一切看起来都很好 - 我已经完成了我的功课,对使用shared_ptrs 的一些陷阱非常了解.
最常见的问题之一shared_ptr是循环依赖 - 这些问题可以通过存储weak_ptr不影响链上对象生命周期的问题来解决.然而,我正在努力解决需要通过以下方式存储指向外部对象的指针weak_ptr- 我不确定它是否被禁止,气馁或是否安全.
下图描述了我的意思(黑色箭头表示shared_ptr;虚线表示weak_ptr):
替代文字http://img694.imageshack.us/img694/6628/sharedweakptr.png
shared_ptr两个子节点,两个子节点都使用a指向父节点weak_ptr. weak_ptr指向第二个子节点的指针并将其存储在本地.代码如下所示:
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/make_shared.hpp>
#include <boost/enable_shared_from_this.hpp>
class child;
class child2;
class parent;
class parent : public boost::enable_shared_from_this<parent>
{
public:
void createChildren()
{
_child2 = boost::make_shared<child2>(shared_from_this());
_child = boost::make_shared<child>(shared_from_this());
}
boost::shared_ptr<child> _child;
boost::shared_ptr<child2> _child2;
};
class child
{
public: …Run Code Online (Sandbox Code Playgroud) 已经有关于一些问题的今天std::weak_ptr和std::owner_less及其关联容器使用std::set和std::map.有很多帖子声明weak_ptr在a 中使用a std::set是不正确的,因为如果弱指针到期,它将是Undefined Behavior.它是否正确?
我需要比较两个websocket ++ connection_hdl:
// Create a weak pointer on the heap using that shared_ptr.
// Cast that weak pointer to void* and manage it using another shared_ptr
// connection_hdl hdl(reinterpret_cast<void*>(new connection_weak_ptr(con)));
Run Code Online (Sandbox Code Playgroud)
我试过这段代码
template <typename T, typename U>
inline bool equals(const connection_hdl<T>& t, const connection_hdl<U>& u)
{
return !t.owner_before(u) && !u.owner_before(t);
}
Run Code Online (Sandbox Code Playgroud)
但编译器抱怨说connection_hdl is not a template.
可以修改上面的代码来比较connection_hdls吗?connection_hdls可以通过使用owner_less与容器一起使用,所以在我缺乏经验的情况下,可以使用所有权来进行比较.
我能找到的唯一其他相关技术是比较weak_ptrs集
bool result = !(std::lexicographical_compare(set1.begin(), set1.end(),
set2.begin(), set2.end(),
set1.value_comp()) ||
std::lexicographical_compare(set2.begin(), set2.end(),
set1.begin(), set1.end(),
set1.value_comp()));
Run Code Online (Sandbox Code Playgroud)
这似乎与我的需求很接近,但由于我的经验不足,我不能确定或修改那些符合我意图的代码. …
到目前为止我所拥有的是:
Observer.h
class Observer
{
public:
~Observer();
virtual void Notify() = 0;
protected:
Observer();
};
class Observable
{
public:
~Observable();
void Subscribe( std::shared_ptr<Observer> observer );
void Unsubscribe( std::shared_ptr<Observer> observer );
void Notify();
protected:
Observable();
private:
std::vector<std::weak_ptr<Observer>> observers;
};
Run Code Online (Sandbox Code Playgroud)
Observer.cpp
void Observable::Subscribe( std::shared_ptr<Observer> observer )
{
observers.push_back( observer );
}
void Observable::Unsubscribe( std::shared_ptr<Observer> observer )
{
???
}
void Observable::Notify()
{
for ( auto wptr : observers )
{
if ( !wptr.expired() )
{
auto observer = wptr.lock();
observer->Notify();
}
} …Run Code Online (Sandbox Code Playgroud) 在macOS上使用线程清理程序运行时,以下代码会产生警告。我看不到比赛在哪里。shared_ptr和weak_ptr的控制块是线程安全的,并且std::queue通过保持锁定来完成从中推入和弹出操作。
#include <future>
#include <memory>
#include <queue>
class Foo {
public:
Foo() {
fut = std::async(std::launch::async, [this] {
while (!shouldStop) {
std::scoped_lock lock(mut);
while (!requests.empty()) {
std::weak_ptr<float> requestData = requests.front();
requests.pop();
(void)requestData;
}
}
});
}
~Foo() {
shouldStop.store(true);
fut.get();
}
void add(const std::weak_ptr<float> subscriber) {
std::scoped_lock lock(mut);
requests.push(subscriber);
}
private:
std::atomic<bool> shouldStop = false;
std::future<void> fut;
std::queue<std::weak_ptr<float>> requests;
std::mutex mut;
};
int main() {
Foo foo;
int numIterations = 100000;
while (--numIterations) {
auto subscriber = std::make_shared<float>(); …Run Code Online (Sandbox Code Playgroud) 我有一个遵循这种模式的课程:
class Foo
{
public:
// Create a Foo whose value is absolute
Foo(int x) : other_(0), a_(x) {}
// Create a Foo whose value is relative to another Foo
Foo(Foo * other, int dx) : other_(other), a_(dx) {}
// Get the value
double x() const
{
if(other_)
return other_->x() + a_;
else
return a_;
}
private:
Foo * other_;
int a_;
};
Run Code Online (Sandbox Code Playgroud)
这些Foo对象都归Bar:
class Bar
{
public:
~Bar() { for(int i=0; i<foos_.size(); i++) delete foos_[i]; …Run Code Online (Sandbox Code Playgroud) 我阅读了关于共享指针并了解如何使用.但我从来没有理解共享指针的循环依赖问题以及弱指针如何解决这些问题.任何人都可以清楚地解释这个问题吗?
std::shared_ptr<int> int_ptr;
int main() {
int_ptr = std::make_shared<int>(1);
std::thread th{[&]() {
std::weak_ptr int_ptr_weak = int_ptr;
auto int_ptr_local = int_ptr_weak.lock();
if (int_ptr_local) {
cout << "Value in the shared_ptr is " << *int_ptr_local << endl;
}
});
int_ptr.reset(nullptr);
th.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码是否安全?我读了这个答案关于weak_ptr的线程安全,但只是想确保上面的代码是线程安全的.
我问这个的原因是,如果上面的代码确实是线程安全的,我无法理解std::weak_ptr和std::shared_ptr接口如何使以下操作成为原子expired() ? shared_ptr<T>() : shared_ptr<T>(*this).在我看来,如果不使用某种互斥锁或自旋锁,就不能使上面这两行逻辑代码同步.
我理解原子增量如何与不同的共享指针实例一起工作,我理解它们shared_ptr本身不是线程安全的,但如果上面确实是线程安全的,那就非常像线程安全shared_ptr而且我不明白两行代码如何就像在条件上面可以做成原子而没有锁.
我正在学习智能指针和shared_from_this. 在类继承关系中,会很难理解。
我有两个基类CA和CB,它们派生自enable_shared_from_this,子类CC派生自CA和CB。我想从类自身中取出三个类的共享指针,所以我写了sharedCAfromThis,sharedCBfromThis和sharedCCfromthis。
class CA : private enable_shared_from_this<CA> {
public:
shared_ptr<CA> sharedCAfromThis() { return shared_from_this(); }
virtual ~CA() {};
void print() {
cout << "CA" << endl;
}
};
class CB : private enable_shared_from_this<CB> {
public:
shared_ptr<CB> sharedCBfromThis() { return shared_from_this(); }
virtual ~CB() {};
void print() {
cout << "CB" << endl;
}
};
class CC : public CA, …Run Code Online (Sandbox Code Playgroud) 我正在开发带有一些类的图书馆,我们称它们为C1, C2 and ... Cn。这些类中的每一个都实现一些接口,即I1, I2, ... Im.(n> m)。库中对象之间的关系很复杂,我必须为我的库用户提供一些API以使用智能指针访问这些对象。
经过一些讨论,我发现将共享指针返回给库用户不是一个好主意,因为在那种情况下,我无法确保可以在库的内存中精确地删除该对象。返回弱指针具有相同的问题,因为如果API .lock()的用户使用了弱指针并将结果共享指针保留在某处,我将再次面临相同的问题。
我的最终想法是为弱指针提供某种包装。包装器类可以是这样的:
class Wrapper_C1 : public I1
{
std::weak_ptr<C1> mC1;
public:
Wrapper_C1() = delete;
Wrapper_C1(const std::weak_ptr<C1> & c1) : mC1(c1)
{
}
int method1_C1(int x)
{
if (auto sp = mC1.lock())
{
sp->method1_C1(x);
}
else
{
throw std::runtime_error("object C1 is not loaded in the lib.");
}
}
void method2_C1(double y)
{
if (auto sp = mC1.lock())
{
sp->method2_C1(y);
}
else
{
throw std::runtime_error("object C1 is …Run Code Online (Sandbox Code Playgroud) c++ ×10
weak-ptr ×10
shared-ptr ×6
c++11 ×5
boost ×1
comparison ×1
cyclic ×1
inheritance ×1
observers ×1
websocket++ ×1