Reputation: 1687
I have basically this setup:
class B { /* ... */};
class C1 : public B { /* ... */};
class C2 : public B { /* ... */};
class X
{
std::vector<shared_ptr<B>> m_vec;
void addToVector(B* b);
}
addToVector
cant know how many classes derive from B and should not care. It will be called like this:
someFunction() {
C1 tmp;
/* do something with tmp */
m_myX.addToVector(&tmp);
}
so at the end of someFunction
, tmp is getting out of scope and will be deleted. addToVector
has to push_back a shared_ptr to a copy of tmp into the vector, but how can it do that?
void X::addToVector(B* b)
{
int i = sizeof(b); // allways sizeof(B) :(
shared_ptr<B> np(b);
m_vec.push_back(np); // garbage collected after calling fn returns :(
}
What it should do is:
How can i do this?
Upvotes: 2
Views: 77
Reputation: 12178
your 'someFunction' looks strange... (why not create tmp
as shared_ptr
in the first place?)
to make it work you will have to create 'virtual constructor' - add virtual method B* deepCopy() const
in B, and implement it in all subclasses, it's body should be based on pattern: { return new DerivedType(*this); }
If you want to be clean - make deepCopy
returning shared_ptr
and using make_shared
.
Upvotes: 2
Reputation: 171373
You are creating an object on the stack and then giving its address to a shared_ptr
which will try to delete
an object on the stack, which is undefined behaviour.
The solution is to stop doing that:
void someFunction() {
C1* c = new C1;
/* do something with *c */
m_myX.addToVector(c);
}
Now you have an object on the heap, which can be owned by a shared_ptr
. There's no need to make a copy of it.
This will only work correctly if B
has a virtual destructor, but that can be avoided (and the code can be made safer and cleaner) by creating a shared_ptr in the first place:
void someFunction() {
auto c = std::make_shared<C1>();
/* do something with *c */
m_myX.addToVector(c);
}
void X::addToVector(std::shared_ptr<B> b)
{
m_vec.push_back(np);
}
Now the heap object is managed by shared_ptr
as soon as it's created, and then safely stored in the vector.
Upvotes: 4