This question arose when programming for Unreal Engine with TFunction<>
but it is fundamentally about C++ and I believe the example is equivalent.
The questions are:
The code:
#include <iostream>
#include <functional>
// Basic class with a callback function expressed as a lambda calling a member function
class Foo {
private:
int i = 0;
public:
Foo(int j){
i = j;
}
// A member function that should be called by a manager
void f(){
std::cout << i << std::endl;
}
// Wrap the member function in a lambda
std::function<void()> wrapper = [&](){f();}; // <---- What happens when object is destroyed before call?
};
// Manager class which calls a specified function after some work
class Manager {
public:
// A function that returns immediately and after some time calls the passed function
void asyncWork(std::function<void()> callback){
// Some work here...
callback();
}
};
int main() {
// Create object
Foo foo(42);
// Create manager
Manager manager;
// Pass the callback function to the manager
manager.asyncWork(foo.wrapper);
return 0;
}
The program does the following:
std::function
wrapping for a member function call. This is done in Unreal Engine using the TFunction<>
type.To answer specific to Unreal Engine, the solution is to use a TWeakObjectPtr
. This requires the class be derived from UObject
.
Assuming that you change Foo
to UFoo : public UObject
then:
TFunction<void()> UFoo::Wrapper()
{
TWeakObjectPtr WeakThis (this);
return [WeakThis]()
{
if (ThisClass* This = WeakThis.Get())
{
// This is a valid object
This->CallPrivateMethod(); // or call This->f() if you want
}
// else the object WeakThis points to has been destroyed
};
}
To generalize to C++, presumably the same method would work with a std::weak_ptr.