Skip to content

Instantly share code, notes, and snippets.

@BewareMyPower
Last active September 4, 2022 16:32
Show Gist options
  • Save BewareMyPower/c2ef2c2b5a46ca5e1fb210d4cc133f12 to your computer and use it in GitHub Desktop.
Save BewareMyPower/c2ef2c2b5a46ca5e1fb210d4cc133f12 to your computer and use it in GitHub Desktop.
c++ shared_ptr cyclic references by capturing shared_from_this()
#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] {});
}
private:
std::shared_ptr<Timer> timer_{make_shared<Timer>()};
};
int main() {
auto producer = make_shared<Producer>();
producer->startTimer();
}
@shibd
Copy link

shibd commented Sep 4, 2022

When executing timer.reset() logic in the doSomething method, which can avoid circular references.

The output mentioned above is produced under the premise of commenting timer.reset(). Is that right?

@BewareMyPower
Copy link
Author

BewareMyPower commented Sep 4, 2022

When executing timer.reset() logic in the doSomething method, which can avoid circular references.

Sorry it's my fault. I removed the doSomething() method now. Resetting the timer could avoid the cyclic reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment