[英]std::shared_ptr custom reference counter
我目前正在處理一個代碼,我需要在代碼的多個部分之間靜態共享一個對象的實例。 所以基本上是一個單身人士。 這個實例將被共享,直到沒有人再使用它。 此時我需要在刪除實際實例之前執行一些清理操作。
如果有人在此之后請求共享實例,它將獲得一個新創建的實例,依此類推。
所以我寫了這樣的東西:
template<typename F>
struct static_filter
{
template<typename ...Args>
static std::shared_ptr<F> get(Args... a)
{
return _inst = _inst ?: std::shared_ptr<F>(new F(a...));
}
static void cleanup()
{
// some cleanup operation over inst
_inst.reset();
}
private:
static std::shared_ptr<F> _inst;
};
template<typename F> std::shared_ptr<F> static_filter<F>::_inst{nullptr};
現在我正在尋找一種自動檢測何時沒有人使用 _inst 的方法。 基本上,每次 _inst 的 use_count() 下降到 1 時,我都想得到一個回調。此時我將能夠清理和重置。
我想避免為此實現我自己的引用計數(應用程序在任何地方都使用 shared_ptr 並且更改為自定義類型會有點煩人)。
我嘗試在我的實例上使用自定義刪除器,大致如下:
template<typename F>
struct static_filter
{
template<typename ...Args>
static std::shared_ptr<F> get(Args... a)
{
return _inst = _inst ?: std::shared_ptr<F>(new F(a..., **static_filter<F>::cleanup**));
}
static void cleanup()
{
// some cleanup operation over inst
_inst.reset();
}
private:
static std::shared_ptr<F> _inst;
};
template<typename F> std::shared_ptr<F> static_filter<F>::_inst{nullptr};
但顯然這不起作用,因為我的參考計數器實際上從未達到 0。
有誰知道是否有辦法使用 shared_ptr 實現這一目標?
謝謝。
您在此處使用shared_ptr
在語義級別上是錯誤的。 您不想持有此static
變量的所有權,而只想通過它進行觀察。 這是std::weak_ptr
的用例。 有了這個靜態變量,您可以觀察對象,如果它存在,則將其作為shared_ptr
返回,並且當其他人持有對它的引用時,不會干擾它的銷毀。
這將如下所示:
template<typename F>
struct static_filter
{
template<typename ...Args>
static std::shared_ptr<F> get(Args... a)
{
// Returns the shared_ptr observed, if it exists and is not expired, empty ptr otherwise
// is atomic
auto shared = _inst.lock();
if(!shared) {
_inst = (shared = std::shared_ptr<F>(new F(a..., **static_filter<F>::cleanup**));
}
return shared;
}
static void cleanup()
{
// Always check if the calling object is really the managed object
// some cleanup operation over inst
_inst.reset();
}
private:
static std::weak_ptr<F> _inst;
};
template<typename F> std::weak_ptr<F> static_filter<F>::_inst{};
請注意,這不是線程安全的(您之前的代碼也不是線程安全的),因為在指針為空時對get
兩個同時調用,都可以看到指針為空,並且都構造了一個F
類型的新對象。 您將不得不添加std::lock_guard
以避免這種情況。
請注意,即使您可以在use_count == 1
上添加回調,這本質上也是不安全的。 這就是為什么std::shared_ptr::unique()
從 C++17 開始被棄用並在 C++20 中被刪除(見 這里和這里)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.