Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit conversion of shared_ptr

Tags:

c++

shared-ptr

I have two shared_ptrs of the classes U and T where T is the base of U.

It is no problem to do an implicit conversion from shared_ptr<U> to shared_ptr<T>. But is is also possible to do a conversion from shared_ptr<T> to shared_ptr<U> ?

I tried the sugested solution:

class T {
public:
  virtual ~T() {}
protected: 
  void fillData() = 0;
};

class Timpl : public T 
{ 
public:
  virtual ~Timpl() {}
protected:
  virtual void fillData() = 0;
};

class U : public Timpl {
public: 
  virtual ~U() {}
protected: 
  virtual void fillData() {...} // fill 
};

typedef  shared_ptr<T> TPtr
typedef  shared_ptr<U> UPtr


TPtr tp = std::make_shared<U>();  
UPtr up = std::static_pointer_cast<U>(tp);    //<-- error here :

error: no matching function for call to 'static_pointer_cast(TPtr)'

note: template std::__shared_ptr<_Tp1, _Lp> std::static_pointer_cast(const std::__shared_ptr<_Tp2, _Lp>&)

note: template argument deduction/substitution failed:

note: 'TPtr {aka boost::shared_ptr}' is not derived from 'const std::__shared_ptr<_Tp2, _Lp>'

Solution for this issue:

mixing of std::shared_ptr with boost::shared_ptr is no good idea.

like image 850
Steve Avatar asked Nov 12 '13 15:11

Steve


People also ask

Can you convert shared_ptr to unique_ptr?

In short, you can easily and efficiently convert a std::unique_ptr to std::shared_ptr but you cannot convert std::shared_ptr to std::unique_ptr .

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).

Can shared_ptr be Nullptr?

A null shared_ptr does serve the same purpose as a raw null pointer. It might indicate the non-availability of data. However, for the most part, there is no reason for a null shared_ptr to possess a control block or a managed nullptr .

What happens when shared_ptr goes out of scope?

All the instances point to the same object, and share access to one "control block" that increments and decrements the reference count whenever a new shared_ptr is added, goes out of scope, or is reset. When the reference count reaches zero, the control block deletes the memory resource and itself.


1 Answers

Yes, use static_pointer_cast:

#include <memory>

struct T { virtual ~T() {} };
struct U : T {};

std::shared_ptr<T> pt = std::make_shared<U>();     // *pt is really a "U"

auto pu = std::static_pointer_cast<U>(pt);

There's also a matching std::dynamic_pointer_cast which returns a null pointer if the conversion isn't possible.

like image 191
Kerrek SB Avatar answered Oct 11 '22 07:10

Kerrek SB