有没有办法检测对象实例是否被删除(在 lambda 中)?
Is there a way to detect if object instance is deleted (in lambda)?
我有这个小模板函数来存储我的回调函数以供以后“回调”。
std::function<void(std::string)> stored_callback;
template<class ReadFileCallback, typename Object, class ...T>
void fileMgr_ReadWithCallback(std::string filename, ReadFileCallback callback, Object* object, T ...params) {
std::cout << "fileMgr_ReadWithCallback is processing file: " << filename << std::endl;
stored_callback= [=](std::string s) {
(object->*callback)(s, params...);
};
}
void calledLater() {
stored_callback("somestring");
}
我在 class 中使用它,如下所示:
void MyClass::Read() {
fileMgr_ReadWithCallback("myfile", &MyClass::ReadResult, this, fileId);
}
这很好用,但我非常担心如果 object
失效(超出范围)它会造成真正的混乱。
因为MyClass
可以放到堆上:
MyClass* c=new MyClass();
c->Read(); // callback stored
delete c; // c invalidated
calledLater(); // ???
如果我尝试 运行 这个,它不会导致任何错误。但是如果某些东西覆盖了 c
之前的 space,它会导致一个可怕的 UB。还是我记错了?
有什么方法可以删除其中任何一个的 c
:
- 不调用
stored_callback
,或者
- 不调用
(object->*callback)(s, params...);
这适合存放 weak_ptr 吗?
stored_callback = [=](std::string s) {
std::weak_ptr<Object> obj = object; //or std::make_shared?
if (auto spt = obj.lock()) (spt->*callback)(s, params...);
};
Is there a way to detect if object instance is deleted
是的,只要您在不想延长生命周期时使用 shared_ptr
, and optionally track it with weak_ptr
管理它的生命周期。
对于“非托管”对象,没有通用的方法来执行此操作,这意味着那些直接通过原始指针或具有自动作用域的本地对象分配和管理的对象。
你无法通过原始指针检测对象是否仍然存在,因为如果它被删除或超出范围,取消引用指针首先是非法的。所以,你必须
- 编写代码以在原始指针存在时不破坏对象(即静态正确性)
- 不使用原始指针而是使用智能指针(很可能是
shared_ptr
和 weak_ptr
)来控制对象的生命周期
- 让对象在被销毁时以某种方式从回调中分离出来(这是侵入性的,因为现在每个可以在回调中使用的对象都需要知道它)
我有这个小模板函数来存储我的回调函数以供以后“回调”。
std::function<void(std::string)> stored_callback;
template<class ReadFileCallback, typename Object, class ...T>
void fileMgr_ReadWithCallback(std::string filename, ReadFileCallback callback, Object* object, T ...params) {
std::cout << "fileMgr_ReadWithCallback is processing file: " << filename << std::endl;
stored_callback= [=](std::string s) {
(object->*callback)(s, params...);
};
}
void calledLater() {
stored_callback("somestring");
}
我在 class 中使用它,如下所示:
void MyClass::Read() {
fileMgr_ReadWithCallback("myfile", &MyClass::ReadResult, this, fileId);
}
这很好用,但我非常担心如果 object
失效(超出范围)它会造成真正的混乱。
因为MyClass
可以放到堆上:
MyClass* c=new MyClass();
c->Read(); // callback stored
delete c; // c invalidated
calledLater(); // ???
如果我尝试 运行 这个,它不会导致任何错误。但是如果某些东西覆盖了 c
之前的 space,它会导致一个可怕的 UB。还是我记错了?
有什么方法可以删除其中任何一个的 c
:
- 不调用
stored_callback
,或者 - 不调用
(object->*callback)(s, params...);
这适合存放 weak_ptr 吗?
stored_callback = [=](std::string s) {
std::weak_ptr<Object> obj = object; //or std::make_shared?
if (auto spt = obj.lock()) (spt->*callback)(s, params...);
};
Is there a way to detect if object instance is deleted
是的,只要您在不想延长生命周期时使用 shared_ptr
, and optionally track it with weak_ptr
管理它的生命周期。
对于“非托管”对象,没有通用的方法来执行此操作,这意味着那些直接通过原始指针或具有自动作用域的本地对象分配和管理的对象。
你无法通过原始指针检测对象是否仍然存在,因为如果它被删除或超出范围,取消引用指针首先是非法的。所以,你必须
- 编写代码以在原始指针存在时不破坏对象(即静态正确性)
- 不使用原始指针而是使用智能指针(很可能是
shared_ptr
和weak_ptr
)来控制对象的生命周期 - 让对象在被销毁时以某种方式从回调中分离出来(这是侵入性的,因为现在每个可以在回调中使用的对象都需要知道它)