I modified the code used in @Timo's answer to try to understand how shared_ptr and custom deleter works.
Here is the link to new code, or right here:
#include <memory>
#include <vector>
#include <iostream>
#include <string>
class TopicPointer
{
public:
TopicPointer(int x) : _x(std::move(x))
{
}
~TopicPointer(){
std::cout << "Deleting " << _x << std::endl;
}
int GetX()
{
return _x;
}
private:
int _x;
};
class Topic
{
std::string name;
std::shared_ptr<TopicPointer> _topicPointer;
public:
Topic(std::string name,std::shared_ptr<TopicPointer> topicPointer) : name(move(name)), _topicPointer(std::move(topicPointer)) {}
~Topic(){
std::cout << "Deleting " << name << std::endl;
}
};
struct Deleter
{
public:
void operator()(TopicPointer* ptr)
{
std::cout << "deleting topic " << ptr->GetX() << '\n';
}
};
class TopicsCache
{
public:
std::unique_ptr<Topic>&& createTopic(std::string name, int y)
{
auto topicPtr = new TopicPointer(y);
return std::move(std::unique_ptr<Topic>(new Topic(move(name),std::shared_ptr<TopicPointer>(topicPtr, Deleter()))));
}
};
class Subject
{
public:
Subject(std::vector<std::unique_ptr<Topic>> &&topics) : _topics (std::move(topics))
{
}
private:
std::vector<std::unique_ptr<Topic>> _topics;
};
TopicsCache cache;
Subject BuildSubject()
{
std::vector<std::unique_ptr<Topic>> topics;
std::cout << "Creating topic 1\n";
topics.emplace_back(std::move(cache.createTopic("a",1)));
std::cout << "Created topic 1\n";
std::cout << "Creating topic 2\n";
topics.emplace_back(std::move(cache.createTopic("b",2)));
std::cout << "Created topic 2\n";
topics.emplace_back(std::move(cache.createTopic("c",3)));
topics.emplace_back(std::move(cache.createTopic("d",4)));
return Subject(std::move(topics));
}
int main()
{
Subject subject = BuildSubject();
std::cout << "Done";
}
As you can see, from the outpu of BuildSubject()
:
Creating topic 1
Deleting a
deleting topic 1
Initialized temp 1
Created topic 1
Creating topic 2
Deleting b
deleting topic 2
Created topic 2
Deleting c
deleting topic 3
Deleting d
The shared_ptr
are deleted before the initialization to temp
variable.
I thought when a shared_ptr is copied the reference count is updated? Also doesn't std::move preserve the reference count?
How to stop the shared_ptr from getting disposed early?
Thanks