我有这个小的模板函数来存储我的回调函数,以便以后进行“回调”。
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");
}
我正在像这样的类中使用它:
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
的先前空间,则将导致可怕的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...);
};
答案 0 :(得分:1)
有没有一种方法可以检测对象实例是否被删除
是的,只要您使用shared_ptr
管理其寿命,并且在不想延长该寿命的情况下可以选择使用weak_ptr
对其进行跟踪。
对于“非托管”对象,没有通用的方法,这意味着直接通过原始指针或具有自动作用域的本地对象分配和管理的对象。
您无法通过原始指针检测该对象是否仍然存在,因为如果该对象被删除或超出范围,则首先取消对指针的引用是非法的。因此,您必须
shared_ptr
和weak_ptr
)来控制对象的生存期