You have violated the rule of 3. You have created an object with a non-trivial constructor, and failed to create a destructor or copy constructor or operator=
.
std::vector<blah> foo(10)
creates a single default constructed blah
, and makes 10 copies of it in foo
. Because you violated the rule of 3, these 10 copies are all identical.
The easiest method would be to do away with the new
:
struct CacheNode {
std::set<int> value;
int timestamp;
CacheNode() : value(), timestamp(0) {}
};
another route would be to use a unique_ptr
for lifetime management, and explicitly copy:
struct CacheNode {
std::unique_ptr<std::set<int>> value;
int timestamp;
CacheNode() : value(new std::set<int>()), timestamp(0) {}
CacheNode(CacheNode&&) = default; // C++11 feature
CacheNode(CacheNode const& other):value(new std::set<int>( *other.value ) ), timestampe(other.timestamp) {}
CacheNode& operator=(CacheNode const& other) {
value.reset(new std::set<int>(*other.value));
timestampe = other.timestamp;
return *this;
}
CacheNode& operator=(CacheNode&& other) = default;
// no need for ~CacheNode, unique_ptr handles it
};
when you want to take the std::set<int>
out of your CacheNode
, call CacheNode().value.release()
and store the resulting std::set<int>*
.
std::shared_ptr<std::set<int>>
would allow shared ownership of the std::set
.
There are other approaches, including making your vector
store pointers to CacheNode
, creating value_ptr<T>
templates that do value semantics, etc.
In C++11, these are relatively easy and safe, because std::vector
will move things around, and move semantics on a value_ptr<T>
won't create a new T
.
I am a bit leery of your plan to have shared std::set<int>
between different CacheNode
, because in general that is bad smell -- the ownership/lifetime of things should be clear, and in this case you have some CacheNode
that own the std::set<int>
and others that don't (because they share ownership). A shared_ptr
can get around this, but often there are better solutions.