2012-08-16 95 views
4

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

+0

你可以改变函数返回美孚或功能采取的shared_ptr ,或者是他们都来自一些第三方库的东西? (如果是这样,也许如果你告诉我们哪一个,我们可以浏览文档并找出其意图。) – abarnert 2012-08-16 17:34:14

+0

这就是为什么采用'shared_ptr'参数不理想,应该避免。 – 2012-08-16 17:49:37

回答

7

这是很简单的:

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

基本上,只要堆上分配一个新的Foo,复制/结果移到了。

+2

不应该是'std :: make_shared (FuncThatReturnsFoo(...))'? – josefx 2012-08-16 17:22:23

+0

@josefx:固定。谢谢! – 2012-08-16 17:30:29

+1

我认为make_shared的模板参数需要明确。 'make_shared (FuncThatReturnsFoo(...))'。 – bames53 2012-08-16 17:33:14

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(); 
0

你可以做到这一点

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

语义上说,它使返回值的副本,但副本构造函数应该被省略。

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如果不延长生命期?

1

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

  1. 在堆上创建一个新的副本,并从一个shared_ptr。
  2. 让从它一个shared_ptr用空缺失者。

首先可以通过编写

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

这工作要做,如果类Foo是复制施工的。第二件事可以通过

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

在这里你不创建对象的新副本。但是,只有在foo超出范围之后,才能保证指针未被访问,这只是安全的。否则,你将访问一个被破坏的对象,你的程序可能会做随机的东西。

相关问题