【问题标题】:How to convert an object instance to shared_ptr instance如何将对象实例转换为 shared_ptr 实例
【发布时间】:2012-10-29 04:09:18
【问题描述】:

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

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

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

sptrB = sptrA->SomeMethod(); 

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

【问题讨论】:

  • SomeMethod 究竟返回了什么?参考?复印件?指针?该引用/复制/指针是如何创建的?
  • 它返回一个值类型(A Copy)。
  • sptrB = boost::make_shared&lt;ObjType&gt;(sptrA-&gt;SomeMethod()); 是一个显而易见的答案,但这不是您想要的,对吧?太复杂了?
  • @jogojapan 解决了我的问题。您可以将其发布为答案吗

标签: c++ boost shared-ptr


【解决方案1】:

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

#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 并没有完全执行 转换 到共享指针;相反,它在堆上创建对象的副本并为此提供内存管理。这可能是也可能不是您需要的。


请注意,这等效于 std::make_shared 在 C++11 中对 std::shared_ptr 所做的操作。


提供您在问题中提到的便捷语法的一种方法是为A 定义一个转换运算符为shared_ptr&lt;A&gt;

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

那么你可以如下使用它:

shared_ptr<A> p = generate();

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

      从 C++ 11 开始,您可以使用 std::make_shared&lt;T&gt;() 函数 (link)

      例子:

      int a = 10;
      std::shared_ptr<int> shared_a = std::make_shared<int>(a);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多