Я создаю лямбда-функцию для запуска кода в другом потоке или просто для его запуска чуть позже, но может случиться так, что объект, сохраняемый лямбда-функцией, будет удален за это время.
Как я могу обнаружить это и не запускать функцию в этом случае?
например
class A
{
public:
A(){}
virtual void test(){std::cout << m;}
int m;
};
int main()
{
A* a = new A();
std::function<void ()> function = [=]()->void
{
//if( pointer to 'a' still valid )
{
a->test();
}
};
delete a;
//or if( pointer to 'a' still valid )
function();
system("pause");
return 0;
}
или обнаружение может быть сделано до выполнения лямбда-функции тоже.
Другая идея состоит в том, чтобы объект «Runnable» оставил лямбда-функцию и зарегистрировал ее в той, которую можно удалить. Затем в деструкторе я бы уведомил Runnable и предотвратил выполнение.
Это был бы хороший способ сделать это?
Вы не можете проверить, был ли удален объект, указанный указателем.
Если он был удален, ваш test () будет иметь неопределенное поведение.
Вот решение:
std::shared_ptr<A> a(new A());
std::weak_ptr<A> weak_a(a);
std::function<void ()> function = [weak_a]()->void
{
if( std::shared_ptr<A> a = weak_a.lock() )
{
// to get the A* from a, do a.get()
// operator-> and *a work however:
a->test();
}
};
a.reset(); // instead of delete
Использование weak_ptr
необязательно — если вы вместо этого сделали это shared_ptr
скопированы в лямбду, время жизни a
будет продлен на время жизни лямбды.
Это требует, чтобы код, который использует a
за пределами лямбда-бе shared_ptr
совместимый.