2012-08-16 54 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超出範圍之後,才能保證指針未被訪問,這只是安全的。否則,你將訪問一個被破壞的對象,你的程序可能會做隨機的東西。

相關問題