Casting boost::shared_ptr(Derived) to boost::shared_ptr(Base)

Recommended Posts

Hello, I have this method which takes a reference to a boost::shared_ptr<Base> as parameter and I'd like to pass a boost::shared_ptr<Derived> to it, but for some reason I can't.
class Base {};

class Derived : public Base {};

int main()
{
boost::shared_ptr<Derived> d (new Derived());
}

Throws:
error: no matching function for call to add(boost::shared_ptr<Derived>&)'

Could you orient me on this? tnx.

Share on other sites
This doesn't work for regular pointers. Why do you expect it to work with smart pointers?

Share on other sites
Then they say c++ alows you to shoot yourself in the foot...

Share on other sites
Quote:
 Original post by SiCraneThis doesn't work for regular pointers. Why do you expect it to work with smart pointers?

Wait...

class Base{	public:	virtual void print () {}};class Derived : public Base{	public:	virtual void print () {cout <<"hello!";}};void add (Base* obj){	obj->print();}int main(){   Derived* d = new Derived();   add (d);   return 0;}

Share on other sites
Base * != Base *&

:O

Share on other sites
I use boost::shared_dynamic_cast for this kind of thing :

struct Base {  virtual void print() {}};struct Derived : public Base {  virtual void print() { std::cout << "Derived\n"; }}; void print(boost::shared_ptr<Base>& obj) {  obj->print();}int main(){   boost::shared_ptr<Derived> d (new Derived());   print(boost::shared_dynamic_cast<Base>(d));}

Are there any situations where this would go wrong?

Share on other sites
Why so complicated? You don't need dynamic_cast for an upcast.

class Base {};class Derived : public Base {};void Bar(const shared_ptr<Base> &base) {}void Foo() {  Bar(shared_ptr<Derived>(new Derived()));}

All that's wrong with your original example is that it's not const-correct.

If you pass a shared_ptr<Base> & (a reference to shared_ptr) to your method, that means the method can put any other object deriving from Base into the shared pointer.

This of course is incompatible with the original pointer, which only takes objects of type Derived, so if your method put an instance of OtherDerived in it, after the method returns, you would end up with a shared_ptr<Derived> that carries an OtherDerived instance.

-

Now if the non-const shared_ptr reference was intentional, you need to cast. But a temporary shared_ptr (without the dynamic cast) should solve that problem, too:

class Base {};class Derived : public Base {};void Bar(shared_ptr<Base> &base) {}void Foo() {  shared_ptr<Derived> derived(new Derived());  shared_ptr<Base> base = derived;  Bar(base);}`

Share on other sites
You're right, shared_dynamic_cast is not appropriate in this situation - I don't think I've properly woken up yet. But there are a bunch of casts in shared_ptr.hpp, which pretty much create the temporary for you, and maybe a bit more explicit as to the intention.

Share on other sites
Quote:
 Original post by CygonNow if the non-const shared_ptr reference was intentional, you need to cast.

No, a cast won't work in standard C++. The result of a cast is an rvalue, and an rvalue can't be bound to a non-const reference.

Share on other sites
Quote:
 Original post by CygonWhy so complicated? You don't need dynamic_cast for an upcast.*** Source Snippet Removed ***All that's wrong with your original example is that it's not const-correct.If you pass a shared_ptr & (a reference to shared_ptr) to your method, that means the method can put any other object deriving from Base into the shared pointer.This of course is incompatible with the original pointer, which only takes objects of type Derived, so if your method put an instance of OtherDerived in it, after the method returns, you would end up with a shared_ptr that carries an OtherDerived instance.-Now if the non-const shared_ptr reference was intentional, you need to cast. But a temporary shared_ptr (without the dynamic cast) should solve that problem, too:*** Source Snippet Removed ***

Cool. The situation I have is that I need to keep a pointer to Derived before passing it to the method that takes a Base. I was trying to avoid having to write the declaration of a Base pointer and asigning the derived to it to be able to pass it to the method.

I guess I'll just pass the shared_ptr by value to the method that is going to do exactly that whitout me being required to code it by myself.

Create an account

Register a new account

• Forum Statistics

• Total Topics
627741
• Total Posts
2978887

• 10
• 10
• 21
• 14
• 14