I have this small template function to store my callback function for later "callback".
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");
}
I'm using it from a class like this:
void MyClass::Read() {
fileMgr_ReadWithCallback("myfile", &MyClass::ReadResult, this, fileId);
}
This works nicely, but I have a terrible fear that it can cause a real mess if object
gets invalidated (goes out of scope).
As MyClass
can be put onto heap:
MyClass* c=new MyClass();
c->Read(); // callback stored
delete c; // c invalidated
calledLater(); // ???
If I try running this, it does not cause any error. But if something overwrites c
's former space, it would cause a terrible UB. Or I'm mistaken?
Is there any way when c
is deleted for either of these:
stored_callback
, or(object->*callback)(s, params...);
Is this good for storing a 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
Yes, so long as you manage its lifetime with shared_ptr
, and optionally track it with weak_ptr
when you don't want to extend that lifetime.
There is no general way to do this for "unmanaged" objects, meaning those allocated and managed directly via raw pointers, or locals with automatic scope.
You can't detect whether the object still exists via a raw pointer, because if it was deleted or went out of scope, dereferencing the pointer is illegal in the first place. So, you must either
shared_ptr
and weak_ptr
) to control the object's lifetime