12

There are several interesting questions on pitfalls with boost::shared_ptrs. In one of them, there is the useful tip to avoid pointing boost::shared_ptr<Base> and boost::shared_ptr<Derived> to the same object of type Derived since they use different reference counts and might destroy the object prematurely.

My question: Is it safe to have both boost::shared_ptr<T> and boost::shared_ptr<const T> point to the same object of type T, or will this cause the same problem?

lytenyn
  • 819
  • 5
  • 21
  • 1
    Can you provide a reference for the Base/Derived claim? – fredoverflow Sep 30 '10 at 07:07
  • http://stackoverflow.com/questions/701456/what-are-potential-dangers-when-using-boostshared-ptr/716112#716112 – lytenyn Sep 30 '10 at 07:11
  • 5
    Base/Derive is 100% safe. It's unsafe to use `get()`. Here is analogous situation without Base: `shared_ptr ptr(new Derived), ptr2(ptr.get());` -- unsafe. – Yakov Galka Sep 30 '10 at 07:16
  • @ybungalobill: Thanks, this was the example I always thought that was safe. You cleared up a severe misunderstanding of mine how boost::shared_ptr works.. – lytenyn Sep 30 '10 at 07:21

1 Answers1

19

It is perfectly safe.

The following code sample:

#include <iostream>
#include <boost/shared_ptr.hpp>

int main(int, char**)
{
  boost::shared_ptr<int> a(new int(5));
  boost::shared_ptr<const int> b = a;

  std::cout << "a: " << a.use_count() << std::endl;
  std::cout << "b: " << b.use_count() << std::endl;

  return EXIT_SUCCESS;
}

Compiles and run fine, and is perfectly correct. It outputs:

a: 2
b: 2

The two shared_ptr share the same reference counter.


Also:

#include <iostream>
#include <boost/shared_ptr.hpp>

class A {};
class B : public A {};

int main(int, char**)
{
    boost::shared_ptr<A> a(new B());
    boost::shared_ptr<B> b = boost::static_pointer_cast<B>(a);

    std::cout << "a: " << a.use_count() << std::endl;
    std::cout << "b: " << b.use_count() << std::endl;

    return EXIT_SUCCESS;
}

Behave the same way. You must, however never build your shared_ptr using a construct like this:

boost::shared_ptr<A> a(new B());
boost::shared_ptr<B> b(static_cast<B*>(a.get()));

a.get() gives the raw pointer and loses all information about reference counting. Doing this, you'll end up with two distinct (not linked) shared_ptr that use the same pointer but different reference counters.

ereOn
  • 53,676
  • 39
  • 161
  • 238
  • Thanks, you are perfectly right. I had a completely different misunderstanding along the lines of ybungalobill's example. Thank you both! – lytenyn Sep 30 '10 at 07:19
  • 1
    I was about to post a question on casting shared_pointer but got the answer here. Thx. – rjoshi Nov 06 '10 at 00:24