I found an example here , about using an observer thread with an weak pointer:
std::thread observer;
void observe(std::weak_ptr<int> wp) {
//Start observer thread
observer = std::thread([wp](){
while(true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
//Try acquiring a shared_ptr from weak_ptr
if(std::shared_ptr<int> p = wp.lock()) {
//Success
std::cout << "Observing: " << *p << "\n";
} else {
//The managed object is destroyed.
std::cout << "Stop\n";
break;
}
}
});
}
But I was wondering why use a weak pointer?
The observer function could very much look like this, using a copy of the shared pointer through the function parameter:
void observe(std::shared_ptr<int> sp) {
observer = std::thread([sp](){
while(true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
if(sp.use_count() > 1) {
//Success
std::cout << "Observing: " << *p << "\n";
} else {
//The managed object is about to be destroyed.
std::cout << "Stop\n";
break;
}
}
});
}
So if the counter for the pointed object is 1 we know for sure that the dinamic object will be deleted when the function returns.
Besides the sharp edges of
use_countthat make it much more difficult to use correctly thanweak_ptr, your program does not behave the same as the initial example.In your code the
shared_ptrcaptured by the thread will keep the object alive as long as the observing thread is running. That means that in the worst case you will have to wait around 1 second after the last owner died before the observed object gets actually destroyed. Contrast that with the initial example where you would at most have to wait for theweak_ptrto release its copy, which is both much less likely to occur and has a much shorter expected effect on the lifetime of the object.In case of an
int, waiting one second for destruction might not seem like a big deal. But consider instead a more pathological example where the observed object executes a substantial operation in its destructor and the observer thread runs with a frequency of a single check per day...