I have a following piece of code, which is creating a simple object of Name and inside that it is creating another object Name, with a shared_from_this()
reference. As I am reading from here https://en.cppreference.com/w/cpp/memory/enable_shared_from_this/shared_from_this
"Effectively executes std::shared_ptr(weak_this), where weak_this is the private mutable std::weak_ptr member of enable_shared_from_this."
Which I am understanding as shared_from_this() is only creating a weak pointer to shared obj. But I don't see this is the case in runtime. There is effectively a circular reference getting created.
At the end of the I was expecting the Name obj should be destructed, but it is not because the reference counter is 2.
Can someone help me understand how should I use enable_shared_from_this()
, that can effectively cleanup the Name obj, once it goes out of reference.
#include <iostream>
#include <memory>
#include <string>
#include <chrono>
#include <thread>
using namespace std;
struct Another;
struct Name : public std::enable_shared_from_this<Name> {
std::string t;
int m, n, p;
shared_ptr<Another> ann;
Name() {
std::cout << "constructor\n";
}
void MakeSomething() {
ann = std::make_shared<Another>(shared_from_this());
}
~Name() {
std::cout << "destructor\n";
}
};
struct Another {
shared_ptr<Name> nn;
Another(shared_ptr<Name> n) : nn(n) {
std::cout << "from another constructor " << nn.use_count() << "\n";
}
~Another() {
std::cout << "from another destructor\n";
}
};
int main()
{
{
auto n = std::make_shared<Name>();
std::cout << "Name ref count so far: " << n.use_count() << "\n";
auto p = n.get();
//delete p;
std::cout << "Name ref count so far: " << n.use_count() << "\n";
n->MakeSomething();
std::cout << "Name ref count so far: " << n.use_count() << "\n";
{
shared_ptr<Name> m = n;
std::cout << "Name ref count so far: " << n.use_count() << "\n";
}
std::cout << "Name ref count so far: " << n.use_count() << "\n";
}
// problem: at this point Name obj, should go out of reference and destructor to be called, which is NOT happening
return 0;
}
And here is the runtime output (compiler used msvc)
constructor
Name ref count so far: 1
Name ref count so far: 1
from another constructor 3
Name ref count so far: 2
Name ref count so far: 3
Name ref count so far: 2
Aucun commentaire:
Enregistrer un commentaire