如何从非指针对象创建std :: shared_ptr?

时间:2012-08-16 17:14:28

标签: c++ shared-ptr

作为一个函数的输出,我得到一个Foo类型的对象。作为另一个类的参数,我需要传递一个std::shared_ptr<Foo>类型的对象。如何从原始对象创建共享指针?

5 个答案:

答案 0 :(得分:7)

这非常简单:

auto val = std::make_shared<Foo>(FuncThatReturnsFoo(...));

基本上,只需堆分配一个新的Foo,将结果复制/移动到其中。

答案 1 :(得分:5)

如果我是你,我不会这样做。主要是因为std::shared_ptr管理内存,而如果将对象作为返回类型,则会自动管理内存(通常,很可能)。

您必须在动态存储中创建新对象

Foo getObject();
//...
std::shared_ptr<Foo> ptr(new Foo(getObject())); //construct new object in dynamic memory
                                                //using the copy constructor

或更改函数以返回指向您管理其内存的对象的指针。

Foo getObject(); 
//becomes
Foo* getObject();
//or, even better
std::shared_ptr<Foo> getObject();

答案 2 :(得分:1)

我怀疑你想要阻止堆分配,否则只是堆分配返回对象的副本并继续。

您需要防止删除器实际删除某些内容并需要堆栈来处理这个问题:

// given the signatures
Foo f();
void other(std::shared_ptr<Foo> x);

Foo my_f = f();
std::shared_ptr<Foo> my_fptr{&my_f, [](Foo*) {}};
other(my_fptr);

但这是一种真正的代码味道。为什么函数会接受a shared_ptr如果不延长寿命?

答案 3 :(得分:1)

有两种方法可以做到这一点:

  1. 在堆上创建一个新副本,并从中创建一个shared_ptr。
  2. 使用空删除器从中创建shared_ptr。
  3. 第一个可以通过写

    来完成
    auto newPtr = std::make_shared<Foo>( foo );
    

    如果类Foo是可复制的,那么这是有效的。

    可以完成第二件事
    auto newPtr = std::shared_ptr<Foot>( &foo, [](void*){} );
    

    此处您不创建对象的新副本。但是,只有在foo超出范围后才能保证不访问指针,这才是安全的。否则,您将访问被破坏的对象,并且您的程序可能会随机执行。

答案 4 :(得分:0)

你可以这样做

std::shared_ptr<Foo> ptr(new Foo(f());

从语义上讲,它正在复制返回值,但应该省略复制构造函数。