-
-
Save shibd/b5cfc707a20205128aadceea4a05fa3a to your computer and use it in GitHub Desktop.
c++ shared_ptr cyclic references by capturing shared_from_this()
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <atomic> | |
#include <functional> | |
#include <iostream> | |
#include <memory> | |
using namespace std; | |
static std::atomic_int idGenerator{0}; | |
struct Object { | |
int id; | |
Object() : id(idGenerator++) { cout << "Create " << id << endl; } | |
virtual ~Object() { cout << "Destroy " << id << endl; } | |
}; | |
class Timer : public Object { | |
public: | |
void async_wait(function<void()> callback) { | |
callback_ = callback; | |
// Assume running callback_() in another thread | |
callback_(); | |
} | |
private: | |
function<void()> callback_; | |
}; | |
class Producer : public Object, public enable_shared_from_this<Producer> { | |
public: | |
void startTimer() { | |
auto self = shared_from_this(); | |
timer_->async_wait([this, self] { doSomething(); }); | |
} | |
private: | |
std::shared_ptr<Timer> timer_{make_shared<Timer>()}; | |
void doSomething() { timer_.reset(); } | |
}; | |
int main() { | |
auto producer = make_shared<Producer>(); | |
producer->startTimer(); | |
} | |
// Outputs: | |
// ``` | |
// Create 0 | |
// Create 1 | |
// ``` | |
// No "Destroy" logs can be seen. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment