Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does one downcast a std::shared_ptr?

Consider:

struct SomethingThatsABase {     virtual bool IsChildOne() const { return false; }     virtual bool IsChildTwo() const { return false; } };  struct ChildOne : public SomethingThatsABase {     virtual bool IsChildOne() const { return true; } };  struct ChildTwo : public SomethingThatsABase {     virtual bool IsChildTwo() const { return true; } };  void SomeClientExpectingAChildOne(std::shared_ptr<ChildOne> const& ptrOne) {     //Does stuff }  void SomeClient(std::shared_ptr<SomethingThatsABase> const& ptr) {     if (ptr->IsChildOne())     {         SomeClientExpectingAChildOne(ptr); //Oops.         //Hmm.. can't static_cast here, because we need a `shared_ptr` out of it.     } } 

(Note that I can't simply do a std::shared_ptr<ChildOne>(static_cast<ChildOne*>(ptr.get())), because then the reference counts don't get shared between the two shared_ptrs)

like image 524
Billy ONeal Avatar asked Jul 22 '11 20:07

Billy ONeal


People also ask

Can you cast a shared pointer?

Casting shared pointers in C++We can either cast the shared pointer directly by setting the type to the DerivedClass, or just use the raw points with “. get()” and static_cast in the second approach (direct cast).

What happens when you move a shared_ptr?

By moving the shared_ptr instead of copying it, we "steal" the atomic reference count and we nullify the other shared_ptr . "stealing" the reference count is not atomic, and it is hundred times faster than copying the shared_ptr (and causing atomic reference increment or decrement).

What does shared_ptr get () do?

A shared_ptr may share ownership of an object while storing a pointer to another object. get() returns the stored pointer, not the managed pointer.

What happens when shared_ptr goes out of scope?

The smart pointer has an internal counter which is decreased each time that a std::shared_ptr , pointing to the same resource, goes out of scope – this technique is called reference counting. When the last shared pointer is destroyed, the counter goes to zero, and the memory is deallocated.


2 Answers

This ought to work:

if (ptr->IsChildOne()) {     SomeClientExpectingAChildOne(std::static_pointer_cast<ChildOne>(ptr)); } 
like image 60
mwigdahl Avatar answered Oct 10 '22 13:10

mwigdahl


The shared_ptr equivalent of static_cast is static_pointer_cast, and the shared_ptr equivalent of dynamic_cast is dynamic_pointer_cast.

like image 32
Joel Avatar answered Oct 10 '22 15:10

Joel