是否可以检测绑定成员函数引用的对象是否被删除或销毁
Is it possible to detect if the object that a bound member function refers to is deleted or destroyed
我正在探索std::function
和std::bind
的使用。我看到您可以绑定成员函数,例如:
class A{
int c_ = 10;
public:
int add(int a, int b){
return a + b + c_;
}
};
int main(){
A* p_a = new A;
std::function<int()> f = std::bind(&A::add, p_a, 1, 1);
printf("%in", f()); // yields "12" (1 + 1 + 10)
delete p_a;
printf("%in", f()); // yields derpy numbers, no errors thrown.
}
有没有办法检测p_a是否已被删除?
我的解决方案是拥有一个包装类来保存函数和对象的weak_ptr
。我只是想知道是否有更优雅的方法可以做到这一点。
std::bind
可以接受智能指针,因此您只需将std::shared_ptr<A>
传递给它即可。
std::shared_ptr<A> p_a(new A);
std::function<int()> f = std::bind(&A::add, p_a, 1, 1);
请注意,函子将拥有该对象:只要函子存在,该对象就会存在。如果您不想要这种行为,那么您带有 weak_ptr
包装器的解决方案很好。
struct A{
int c_ = 10;
int add(int a, int b){
return a + b + c_;
}
};
template<class T>
std::weak_ptr<T> weak( std::shared_ptr<T> const& sp ) { return {sp}; }
int main(){
auto p_a = std::make_shared<A>();
std::function<int()> f = [w_a = weak(p_a)]() {
if (auto p_a = w_a.lock())
return p_a->add(1,1);
throw w_a;
}
printf("%in", f()); // yields "12" (1 + 1 + 10)
p_a.reset();
try {
printf("%in", f()); // yields derpy numbers, no errors thrown.
} catch( std::weak_ptr<A> wp ) {
printf("object deletedn");
}
}
活生生的例子。
一般来说,在C++中,您无需为不使用的东西付费。
跟踪对象的生存期是有代价的。 如果要跟踪对象的生存期,可以使用对(免费存储)分配对象的shared_ptr
或weak_ptr
,或者使用对对象拥有的shared_ptr
(唯一)的weak_ptr
来指示其生存期已结束。
上面是一个使用 C++14 lambda 将对象的共享指针捕获为弱 ptr 的实现,并在已删除时给出定义的行为(抛出所述弱指针的副本)。
生命周期令牌如下所示:
using lifetime_token = std::weak_ptr<void>;
struct has_lifetime {
has_lifetime():token(std::make_shared<char>()) {}
has_lifetime(has_lifetime const&o):has_lifetime() {} // not default
lifetime_token get_lifetime() const {
return token;
}
private:
std::shared_ptr<void> token;
};
从 has_lifetime
继承会给你一个get_lifetime()
成员,只要你存在(它被析构函数销毁,不能再.lock()
d)。
如果无法修改原始类的所有权语义,则更容易遵循此模式。 只需.lock()
物体的lifetime_token
即可确定它是否还活着。
相关文章:
- 是否需要删除包含对象的"pair"?
- 是否删除在对象构造过程中创建的对象
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 在这种情况下,java对象是否可以调用本机函数
- 返回指向对象的指针的函数调用是否为 prvalue?
- 具有引用成员的结构是否具有唯一的对象表示形式
- 对象初始化中是否允许指向此成员的指针?
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- 堆分配的对象是否存在永不为空的唯一所有者?
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- 是否可以使用一个类来控制 C++ 中另一个类的对象?(阿杜伊诺)
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- QFileSystemModel 对象是否会被删除?
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 是否可以使用分配器对象来释放另一个分配器分配的内存?
- 线程调用的函数对对象删除是否安全?
- 将对象的字节复制到数组并再次复制回来是否安全
- std::memmove在同一对象之间是否始终安全
- 类对象在 c++ 中是否具有数据类型?
- 是否可以将不可复制的成员用作使对象不可复制的替代方法?