5

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

4

5 回答 5

7

这真的很简单:

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

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

于 2012-08-16T17:18:02.910 回答
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();
于 2012-08-16T17:16:44.750 回答
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);

不过,那是一种真正的代码气味。shared_ptr如果不是为了延长生命周期,为什么函数会接受 a ?

于 2012-08-16T17:22:31.873 回答
1

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

  1. 在堆上创建一个新副本并从中创建一个 shared_ptr 。
  2. 使用空删除器从中创建一个 shared_ptr 。

第一个可以通过写来完成

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

如果该类Foo是可复制构造的,则此方法有效。第二件事可以通过

auto newPtr = std::shared_ptr<Foot>( &foo, [](void*){} );

在这里,您不会创建对象的新副本。但是,这只是安全的,如果您可以保证指针在foo超出范围后不被访问。否则,您将访问一个被破坏的对象,并且您的程序可能会做一些随机的事情。

于 2012-08-16T17:36:32.273 回答
0

你可以这样做

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

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

于 2012-08-16T17:18:22.937 回答