no matching function for call to `std::stack<boost::shared_ptr<Base>, std::deque<boost::shared_ptr<Base>, std::allocator<boost::shared_ptr<Base> > > >::push(Derived*)'
note C:\MinGW\include\c++\3.4.5\bits\stl_stack.h:191 candidates are: void std::stack<_Tp, _Sequence>::push(const typename _Sequence::value_type&) [with _Tp = boost::shared_ptr<Base>, _Sequence = std::deque<boost::shared_ptr<Base>, std::allocator<boost::shared_ptr<Base> > >]
Polymorphic Smart Pointers
Is there a way that I can use polymorphism with smart pointers? More specifically, I have a std::stack of boost::shared_ptr<Base>. But when I tried stack.push(new Derived), the compiler gave me the following error:
Is there a way to do this?
Just to add to the above post, it is potentially dangerous to use an unnamed temporary shared_ptr as it has the potential to cause a memory leak.
Something like this would be a better alternative.
Something like this would be a better alternative.
boost::shared_ptr<Base> obj(new Derived(/*constructor arguments here*/));stack.push(obj);
Quote:Original post by vtchill
Just to add to the above post, it is potentially dangerous to use an unnamed temporary shared_ptr as it has the potential to cause a memory leak.
Something like this would be a better alternative.
*** Source Snippet Removed ***
Actually it isn't a problem in that case. It would only be a problem if the function accepted multiple arguments.
reference
Sweet, thanks to all! I'll try it out. I'm getting to the point where I'm using more and more polymorphic objects and I don't want to worry about memory leaks, so I figured I'd try to use some smart pointers for some extra safety.
[edit]
Works perfectly!
[edit]
Works perfectly!
To get back to the original post, a boost::shared_ptr<Base> can definitely be set to point to a Derived. I don't know why the compiler is giving you an error there but this really *should* work IMO.
P.S. Ah never mind ... I should learn to read posts before writing replies.
P.S. Ah never mind ... I should learn to read posts before writing replies.
Quote:Original post by Red Ant
I don't know why the compiler is giving you an error there but this really *should* work IMO.
It doesn't because the shared_ptr constructor that takes a single pointer is explicit.
Yeah sorry ... I hadn't read the post properly before replying. I see now that he was relying on an implicit conversion.
Quote:Original post by fpsgamerQuote:Original post by vtchill
Just to add to the above post, it is potentially dangerous to use an unnamed temporary shared_ptr as it has the potential to cause a memory leak.
Something like this would be a better alternative.
*** Source Snippet Removed ***
Actually it isn't a problem in that case. It would only be a problem if the function accepted multiple arguments.
reference
youch ... i never considered this. my code has a lot of this kind of thing, (the justification for the init() seperate from the constructor is for dealing with things that interact with shared_from_this())
class A{ typedef shared_ptr< A> ptr; static ptr create() { ptr p( new A); p->init(); return p; }};
is it safe to use in this type of context.
vector< A::ptr> va; va.push_back( A::create() );
i think its ok - its still a temporary being returned that is used as the const arg of the push_back method, but both the shared pointer and underlying object have been fully constructed and use_count() is always positive even if its only being held by a temporary. what about multiple argument functions . if one of the other arguments methods throws on the constructor - would that still be memory safe ?
Quote:Original post by chairthrower
i think its ok - its still a temporary being returned that is used as the const arg of the push_back method, but both the shared pointer and underlying object have been fully constructed and use_count() is always positive even if its only being held by a temporary. what about multiple argument functions . if one of the other arguments methods throws on the constructor - would that still be memory safe ?
The scenario you illustrated is safe.
The problem (as you've already noted) has to do with when you are dealing with multiple arguments.
Consider this:
void doStuff(boost::shared_ptr<Foo>(new Foo()), Bar() );
The order in which arguments are evaluated in C++ is undefined. If an exception is thrown at inopportune times you will get a resource leak. Consider this hypothetical argument evaluation order:
(1) exectute 'new Foo()'
(2) construct temporary Bar() object
(3) construct shared_ptr<Foo> from the value returned by 'new Foo()'
If (2) two throws an exception, stack unwinding will commence and we will loose a handle to the memory allocated in (1).
Thats why you should do this instead:
boost::shared_ptr<Foo>ptr(new Foo());
void doStuff(ptr, Bar() );
If stack unwinding begins as the result of a thrown exception, the shared_ptr will be destroyed and take appropriate care of the heap resource.
Further Reading.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement