Сделать boost :: shared_ptr <T>и повысить :: shared_ptrподелиться ссылками? - PullRequest
12 голосов
/ 30 сентября 2010

Есть несколько интересных вопросов о подводных камнях с boost::shared_ptr с. В одном из них есть полезный совет, чтобы не указывать boost::shared_ptr<Base> и boost::shared_ptr<Derived> на один и тот же объект типа Derived, поскольку они используют разные счетчики ссылок и могут преждевременно уничтожить объект.

Мой вопрос: безопасно ли указывать boost::shared_ptr<T> и boost::shared_ptr<const T> на один и тот же объект типа T, или это вызовет одну и ту же проблему?

1 Ответ

19 голосов
/ 30 сентября 2010

Это совершенно безопасно.

Следующий пример кода:

#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;
}

Компилируется и работает нормально, и это совершенно правильно. Выводит:

a: 2
b: 2

Два shared_ptr используют один и тот же счетчик ссылок.


Также:

#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;
}

Веди себя так же. Однако вы должны никогда строить свой shared_ptr, используя такую ​​конструкцию:

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

a.get() дает необработанный указатель и теряет всю информацию о подсчете ссылок. В результате вы получите два разных (не связанных) shared_ptr, которые используют один и тот же указатель, но разные счетчики ссылок.

...