簡體   English   中英

移動語義與返回shared_ptr?

[英]Move semantic vs returning a shared_ptr?

我理解在C ++程序員中鼓勵使用值語義。 但在我的工作中,我注意到一些程序員使用引用語義的模式,確切地說,他們使用shared_ptr,我將使用值語義。

例如,為了給這個有點上下文,我有一個讀取數據庫頁面並返回其內容的API。 我看到有兩種方法可以做到這一點。

選擇1值語義:

DBPage readDatabasePage(int number) { // number is the for which page to read
    DBPage page;
    ... // reading the database page

    return page; // here we have RVO/move semantic to help us so it is not inefficient
} 

選擇2參考語義:

std::shared_ptr<DBPage> readDatabasePage(int number) { // ditto
    std::shared_ptr<DBPage> page = std::make_shared<DBPage>();
    ...
    return page;
}

第二種選擇對我來說似乎沒問題,因為我看不出這樣做的缺點。 所以我想要理解的是為什么我們鼓勵人們使用價值語義。 選擇2有什么問題?

默認情況下,值語義是首選,因為它不分配內存=>沒有內存泄漏,沒有損壞的內存等。

每種指針類型都有自己的語義。 shared_ptr只有在它控制的資源將被共享時才應該使用,所以它一直存在到最后一個引用(指針)之前。 在您的示例中, shared_ptr是不合適的。 如果希望在你的例子中使用指針(例如DBPage太大而無法存儲在堆棧中),那么它應該是unique_ptr

您的示例可能不完整,之后結果將確實“共享”。 我要說甚至在這種情況下應該使用unique_ptr ,然后將其“轉換”為shared_ptr ,否則函數簽名會產生誤導,有時這是用戶唯一可見的東西。 雖然在這種情況下它是有爭議的。

此外, shared_ptrunique_ptr慢,並且比std::move慢得多,因為它使用原子操作進行引用計數。 與簡單的int.operator++相比,它們非常昂貴,盡管它僅在性能關鍵的情況下才是問題。

這取決於DBPage的復制成本。 例如,如果DBPage是包含一些指向數據的指針的類,則復制可能很便宜,並且將其存儲在shared_ptr可能會增加不必要的開銷。

另一方面,也許DBPage復制起來很昂貴。 你提到RVO並移動語義,從函數返回DBPage時這些都很好,但是如果用戶實際上想要保留兩個引用相同數據的變量,並且他們希望數據的生命周期是兩個變量的最大值'生命周期,然后shared_ptr是一個自然的契合。

如果用戶最終需要shared_ptr<DBPage>但你給他們DBPage ,他們可能需要復制數據以獲得他們想要的東西。

簡而言之,您需要了解您的用戶和實際的數據。

您有兩種不同的情況需要創建對象。 您的“值語義”在您希望某些內存成為返回對象(堆棧內存,數組中的內存等)的情況下運行良好。 當您希望對象的生命周期超出其范圍(並且存在於堆中)時,您的“引用語義”非常有用。

要專門解決您的問題, 當您想將結果存儲在std::vector<DBPage>選項2將不易使用 即使使用移動語義,為工作提供正確的功能也是更好的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM