15

假设我有两个 shared_ptr 类型,例如

boost::shared_ptr<ObjA> sptrA;
boost::shared_ptr<ObjB> sptrB;

现在假设sptrA->SomeMethod()返回一个简单的 ObjB 类型(不是共享 ptr)。我可以以某种方式将该类型存储在 sptrB 中吗?这样我就可以做这样的事情,以便返回的类型实例自动转换为 boost_shared ptr

sptrB = sptrA->SomeMethod(); 

我只是出于好奇而问了这个问题,这是否可能?

4

3 回答 3

5

boost:shared_ptr创建对象最标准的方法是使用make_sharedBoost 提供的函数:

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

struct A {};

A generator() {
  return A();
}

int main()
{
  using namespace boost;
  shared_ptr<A> p = make_shared<A>(generator());
  return 0;
}

由于该generator()函数按值返回一个A对象,因此上面的语法意味着new使用 的复制构造函数调用它A,并且结果指针被包装在一个共享指针对象中。换句话说,make_shared并没有完全执行到共享指针的转换;相反,它在堆上创建对象的副本并为此提供内存管理。这可能是也可能不是您需要的。


请注意,这等同于 C++11std::make_shared中的 for 。std::shared_ptr


提供您在问题中提到的便捷语法的一种方法是将转换运算符定义为shared_ptr<A>for A

struct A {
  operator boost::shared_ptr<A>() {
    return boost::make_shared<A>(*this);
  }
};

然后你可以按如下方式使用它:

shared_ptr<A> p = generate();

这将自动“转换”函数返回的对象。同样,这里的转换实际上意味着堆分配、复制和包装在共享指针中。因此,我不确定是否建议定义这样一个方便的转换运算符。它使语法非常方便,但它与所有隐式转换运算符一样,也可能意味着您隐式地导致这些“转换”发生在您没有预料到的地方。

于 2012-10-29T06:28:02.537 回答
1

这完全取决于ObjA::SomeMethod返回的内容——副本、引用或指针。在前两种情况下,将其包装成 a 是不可行的shared_ptr(因为shared_ptr需要一个指针)。

第三种情况是可能的,但您必须谨慎行事。确保一旦将指向对象的指针包装到 ashared_ptr中,没有其他人会尝试管理该对象的生命周期。

例如,如果您返回一个原始指针,将其包装成一个共享指针,然后在程序稍后的某个时间点,有人delete使用相同的指针,您就会遇到问题。

于 2012-10-29T04:32:19.937 回答
1

从 C++ 11 开始,您可以使用std::make_shared<T>()函数(链接)

例子:

int a = 10;
std::shared_ptr<int> shared_a = std::make_shared<int>(a);
于 2021-07-29T07:57:06.097 回答