boost::shared_ptr<T>和boost::shared_ptr<const T>共享引用计数吗?

12
有关使用boost::shared_ptr时的一些有趣问题需要注意。其中之一是有一个有用的提示,可以避免将boost::shared_ptr<Base>和boost::shared_ptr<Derived>指向相同类型为Derived的对象,因为它们使用不同的引用计数,并可能过早销毁对象。
我的问题是:是否安全将boost::shared_ptr<T>和boost::shared_ptr<const T>都指向同一类型为T的对象,或者会导致相同的问题?

1
你能提供关于基类/派生类声明的参考资料吗? - fredoverflow
https://dev59.com/kXRB5IYBdhLWcg3wJklC#716112 - lytenyn
5
Base/Derive是100%安全的。使用“get()”是不安全的。这里有一个没有Base的类似情况:“shared_ptr<Derived>ptr(new Derived), ptr2(ptr.get());”--不安全。 - Yakov Galka
@ybungalobill:谢谢,这个例子我一直认为是安全的。你解决了我对boost::shared_ptr工作原理的严重误解。 - lytenyn
1个回答

19

这是完全安全的。

以下代码示例:

#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,它们使用相同的指针但具有不同的引用计数器。


谢谢,你说得完全正确。我曾经有一个完全不同的误解,类似于ybungalobill的例子。谢谢你们两个! - lytenyn
1
我正准备在这里发一个有关 shared_pointer 类型转换的问题,但已经在这里找到了答案。谢谢。 - rjoshi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接