2016-01-14 44 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的所有者,那么您将极大地增加分段错误,堆损坏和其他您不想要的东西的概率。