对于struct:
struct A {
int var = 10;
void check() {
std::cout << "var is " << var << std::endl;
}
};
假设我使用动态分配的A::check()
对象创建a
的std :: function对象:
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
或针对f
测试nullptr
不起作用。
答案 0 :(得分:2)
嗯,这个很容易,请使用std::shared_ptr
。
当你考虑它时,你基本上想要确保你程序中的某个实体只要有东西使用它就有效。
换句话说,您正在寻找shared_ptr
。
否则,设计看起来有点奇怪,如果程序中的某个实体拥有a_ptr
,它应该是使用此资源的所有std::function
的单一所有者,而不是你的意图。如果该所有者不是std::function
的所有者,则会大大增加分段错误,堆损坏和其他您不想要的内容的可能性。
答案 1 :(得分:2)
所以你基本上希望你的函数对象测试由A
管理的a_ptr
实例的存在,我看到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();
这要求在函数对象处于活动状态时指针仍处于活动状态。
- 带有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)。
您还可以使用自己的基元创建更精细的系统,但这会使您远离标准库。最终,您必须根据对象的生命周期和所有权关系选择最适合您情况的东西。