2013-07-23 117 views
3

我如何可以通過智能PTR採取參考指針作爲參數的函數嗎?傳遞智能指針採取參考指針參數的函數

smart_ptr<T> val; // I have this smart pointer 

// And I want to pass it to this function, so that this function will fill the smart pointer with proper value 
void Foo(T*& sth) 
{ 
    sth = memoryAddress; 
} 

編輯 現在我明白了。謝謝你們所有的答案!

+0

您的意思是:'shared_ptr'? – avakar

回答

7

簡單的答案是,你不能。雖然智能指針 幾乎肯定包含T*內部某處,智能 指針執行各種不變量,其中有許多可能是 打破,如果你能不經過 用戶界面改變這個指針。唯一的解決辦法是調用函數 與原始指針,然後使用原始指針初始化 智能指針,提供你是確保 你得到的指針滿足智能指針的要求(例如,由new運營商分配的 )。

1

你不能做到這一點。您可以使用「T* raw = val.get()」,然後「Foo(raw)」將原始指針,但你不能設置一個shared_ptr的原始指針一樣,裏面Foo。如果你想Foo設置shared_ptr,使其採取非const shared_ptr參考。

像這樣:

template<typename T> 
Foo(shared_ptr<T>& ptr) 
{ 
    ptr.reset(memoryAddress); // Or assign it, or make_shared, or whatever. 
} 

shared_ptr<int> intptr; 
Foo(intptr); 

或者更好的是,讓Foo回報shared_ptr,而不是把它作爲參考。

+0

'Foo(val.get())'不應該編譯。如果是這樣,你的編譯器壞了。 –

+0

你說得對。如果你通過臨時的方式,它會有效。我會更新我的答案。 –

+0

如果他可以將界面更改爲「Foo」,那麼他可能會做得對,並且將'Foo' _return'指針指向一個指針。 –

4

哎,這個API是醜陋的。

我將假設該函數承諾它返回的指針擁有一個資源,這個資源將被smart_ptr這樣刪除,並且smart_ptr可以從任意指針初始化。否則無法完成。

您可以像沒有智能指針那樣抓住指針,然後將其放入智能指針中。

T* ptr; 
Foo(ptr); 
smart_ptr<T> val(ptr); 

這可能是智能指針已經擁有的東西的情況下,你想傳遞的東西的功能,然後更換智能指針擁有什麼。那是......更醜陋。

我不知道是否該函數將帶你通過資源的所有權(通常情況下,我希望不會,但是由於API是這個醜陋,我不打算用它來發誓)。這導致了兩種不同的情況。

如果函數需要你傳遞的資源,即所有權,它關心刪除指針本身,智能指針類型必須是一個可以放棄資源的所有權,就像std::unique_ptrrelease()成員函數。值得注意的是,std::shared_ptr不能做到這一點(考慮其他shared_ptr S還可以擁有它)。

因此,假設智能指針具有這種能力,並且能夠被重新初始化爲任意的指針(像std::unique_ptr::reset),你可以做如下:

//smart_ptr<T> val; 
T* ptr = val.release(); 
Foo(ptr); 
val.reset(ptr); 

如果函數不採取所有權的資源,所需要的只是使用任意指針重新初始化的能力。

//smart_ptr<T> val; 
T* ptr = val.get(); 
Foo(ptr); 
val.reset(ptr); 
+3

我想確保返回的指針首先滿足智能指針的要求。能夠設計這樣一個破壞的接口的人也能夠使用'malloc'。 –

+0

@詹姆斯是的,這正是我第二段中的第一個假設。 –

+0

所以我明白了。關於入口參數與函數做什麼的觀點也是很好的一點。 _Usually_,這些功能不會做任何事情,但你永遠不知道。 –