gpt4 book ai didi

c++ - 重新创建一个基于 shared_ptr 的单例

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:15:19 26 4
gpt4 key购买 nike

有一个static shared_ptr<MyClass> get()有一个 weak_ptr内部使用 ptr.lock() 提供共享指针.

ptr.lock()给出一个空指针,应该再次创建单例。

但是它是否保证(它不保证)前一个单例的析构函数已经完成?对此可以做些什么?

最佳答案

But does it guarantee (it doesn't) that the destructor of the previous singleton has completed? What can be done about that?

这是一个不寻常的请求,但我知道如果您要控制外部单例资源,它可能是必要的。

这是我的解决方案。

确保在生产中使用之前彻底检查它

#include <memory>
#include <mutex>
#include <condition_variable>

struct tricky_object
{

};


class tricky_cache
{
struct statics {
std::mutex _m;
std::condition_variable _deleted;
bool _exists = false;
std::weak_ptr<tricky_object> _cache;
};

static statics& get() {
static statics _;
return _;
}

public:
static
std::shared_ptr<tricky_object> acquire()
{
// get static data
auto& data = get();

// lock the cache's mutex
auto lock = std::unique_lock<std::mutex>(data._m);
std::shared_ptr<tricky_object> candidate;

// wait on the condition variable for the following conditions to be true:
data._deleted.wait(lock, [&data, &candidate] {

// either the object is in play and we have acquired another reference...
candidate = data._cache.lock();
if (candidate)
return true;

// ... or (if not) the previous object is actually dead and buried.
return !data._exists;
});

// at this point we still own the lock and wait must have returned true, so...
// if we own the candidate then it was already in play
if (candidate)
return candidate;

// otherwise the previous object is certainly destroyed and we may create another
data._cache = candidate = std::shared_ptr<tricky_object>(new tricky_object(),
[&data](tricky_object*p) {
// but the custom deleter needs some trickery
delete p;
if (p) {
auto lock = std::unique_lock<std::mutex>(data._m);
data._exists = false;
lock.unlock();
data._deleted.notify_all();
}
});
// and we should record the fact that the object now exists...
data._exists = true;
lock.unlock();
// ... and inform all waiters that they may continue acquiring
data._deleted.notify_all();
return candidate;
}
};


int main()
{
auto p = tricky_cache::acquire();

return 0;
}

关于c++ - 重新创建一个基于 shared_ptr 的单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34360942/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com