2013-01-03 59 views
3

我是C++新手。我假定std::string使用引用計數來確定何時釋放緩衝區。在以下示例中,當f()返回時,s緩衝區將被釋放。如果我想將字符串緩衝區的所有權授予give_ownership_of而不是釋放它?我可以從C++中的std :: string分離緩衝區嗎?

void f() 
{ 
    string s = read_str(); 
    give_ownership_of(s); 
} 

UPDATE

讓我補充更多的細節到的問題。實際的代碼看起來是這樣,

string read_str(); 

void write_str_async(const char *str, void (*free_fn)(const char*)); 

void f() { 
    string s = read_str(); 
    // write_str_async() need to access the buffer of s after f() returns. 
    // So I'm responsible to keep s alive until write_str_async() calls free_fn to release the buffer when the write is done. 
    // The PROBLEM here is that s will be released when the variable scope ends. NOTE: I'm not able to change either read_str() or write_str_async() here. 
    write_str_async(s.c_str(), my_free_fn); 
} 
+1

一些實現**在內部使用引用計數機制。它是否引起你的問題? –

+1

你有什麼特別的理由想要獲得內部'char *'緩衝區的所有權,而不是傳遞'std :: string'對象嗎? – LihO

+0

我不確定這可以做到嗎? – james82345

回答

1

有采取std::string的基礎數據的所有權是沒有標準的方式。通常,應該自己返回一個字符串對象或者讓調用者傳入一個引用,例如

void f(std::string& s) { 
    s = read_str(); 
} 
4

在C++ 11中,他們添加了類似這樣的東西,稱爲移動。 std::string有一個移動構造函數和一個移動賦值運算符。

這裏的編譯器可以確定s已達到其壽命結束,因此而不是複製到give_ownership_of它可以移動,它基本上只是複製幾個整數/指針周圍,而不是std::string的內容。請注意,這比通過引用傳遞還要慢,所以如果引用對你有用,那麼不管你喜歡那個。

https://akrzemi1.wordpress.com/2011/08/11/move-constructor/

我會強烈建議不要使用std::shared_ptr這一點,因爲有所有權沒有實際的共享。

在情況下,你想移動明確,那麼你可以這樣做:

give_ownership_of(std::move(s)); 

請注意,您並不需要(事實上也不應該)返回從一個值時使用std::move功能。只需正常返回值。編譯器在很多情況下可以執行「返回值優化」,這意味着沒有複製和移動。它類似於通過引用傳遞值並分配給它,除了它實際上給優化器多一點空間(因爲它知道std::string是一個不會別名的唯一對象)。閱讀也更直接。

0

這個問題不明確,但下面的例子應該說明所有的選擇。最後一個可能是你想要的,這是一個新增加的特性,在C++ 11(std::move和右值引用)中。

這允許您將緩衝區傳輸到同一類型的新對象,但是您永遠無法完全消除std::string。您可以忽略該string並將緩衝區內存視爲字節,但必須通過銷燬string來執行釋放。

// will retain s for duration of function 
void give_ownership_of(std::string &s); 

// will retain a copy of s for duration of function 
void give_ownership_of(std::string s); 

struct give_ownership_of { 
    std::string s; 

    // will retain a copy of in_s for object lifetime 
    give_ownership_of(std::string const &in_s) : s(in_s) {} 

    // will transfer buffer of in_s to s and retain that (C++11 only) 
    // you would write give_ownership_of(std::move(s)); 
    give_ownership_of(std::string &&in_s) : s(std::move(in_s)) {} 
}; 
相關問題