2016-01-14 42 views
1

對於結構後:測試的std ::功能有效性結合成員函數

struct A { 
    int var = 10; 
    void check() { 
     std::cout << "var is " << var << std::endl; 
    } 
}; 

說我創建的A::check()一個std ::功能對象,使用動態分配的a對象:

auto a_ptr = std::make_unique<A>(); 
std::function<void()> f = std::bind(&A::check, a_ptr.get()); 
//...later/elsewhere... 
f(); 

如果我可以測試f以查看綁定的A對象是否仍然存在,那將會很安全。是否可以直接從f檢索該信息?假設a_ptr不能從呼叫點訪問,所以我無法直接對a_ptr進行測試。使用std::function的運營商bool或測試fnullptr不起作用。

+3

你基本上問[this](http://stackoverflow.com/q/11680680/636019)(假設這是[XY問題](http://meta.stackexchange.com/q/66377/166663) ))? – ildjarn

+0

不確定這是一個XY問題,而是使用'std :: weak_ptr'並在調用之前檢查它是解決此問題的體面解決方案。 – TartanLlama

+0

@TartanLlama:首先使用'bind'而不是lambda是什麼使它成爲IMO的XY問題。 – ildjarn

回答

2

所以,你基本上想要你的函數對象來測試由a_ptr管理的A實例的存在,我看到了3種使用當前C++ std特性的方法。

- LAMBDA與該unique_ptr

auto a_ptr = std::make_unique<A>(); 
std::function<void()> f = [&] { if (a_ptr) a_ptr->check(); }; 
//...later/elsewhere... 
f(); 

這是一個參考要求指針仍然活着隨時函數對象是活的。

- LAMBDA用的shared_ptr

auto a_ptr = std::make_shared<A>(); 
std::function<void()> f = [=] { if (a_ptr) a_ptr->check(); }; 
//...later/elsewhere... 
f(); 

同樣的事情,但沒有在上一些額外的性能成本爲代價的壽命關係的要求,其副本主要是共享指針的拷貝,大概完全值得在大多數情況下節省的頭痛(我將被優化傢伙燒掉)。

- 在你的智能指針定製刪除一個重置你的函數

std::function<void()> f; 
auto a_ptr = std::unique_ptr<A, std::function<void(A*)>>(new A, [&](A*){ f = nullptr;}); 
f = std::bind(&A::check, a_ptr.get()); 
//...later/elsewhere... 
a_ptr.reset(); 
if (f) 
    f(); 

這需要以某種方式您缺失者可以訪問該功能將其復位,無論是直接或通過在存儲系統中的類(功能的容器是一個很好的設計imo)。


你也可以用你自己的原語創建更詳盡的系統,但這會導致你遠離標準庫。最終,您必須根據您的情況選擇最適合您的情況,主要基於您的對象的使用壽命和所有權關係。

2

那麼,這一個很容易,使用std::shared_ptr

當你想到它的時候,你基本上想要確保你的程序中的某個實體只要有東西在使用它就是有效的。
換句話說,您正在尋找一個shared_ptr

否則,設計看起來有點奇怪,如果程序中的某個實體擁有a_ptr,它應該是使用此資源的所有std::function的單個所有者,這不是您的意圖。如果該所有者不是std::function的所有者,那麼您將極大地增加分段錯誤,堆損壞和其他您不想要的東西的概率。