2016-08-11 75 views
-5
class myMem{}; 

class Test{ 
public: 
    initMem1(myMem& mInput){/*initialize _mem1*/} 
    initMem2(shared_ptr<myMem> &pmInput){/*initialize _mem2*/} 

    myMem _mem1; 
    shared_ptr<myMem> _mem2; 
}; 

Test myTest; 
myTest() 

因此,在上面的代碼中,成員屬於一個類。一個成員是一個值類型,另一個成員是shared_ptr類型。對於班級成員來說哪種方式更好?此外,我還有初始化成員的功能。哪種方法更好?直接通過引用傳遞給shared_ptr的好處是,通過引用直接傳遞

一般來說,通過引用傳遞給shared_ptr而不是直接傳遞引用的優點是什麼?

+4

...一個需要你有'shared_ptr'? – GManNickG

+3

這個問題應該是:「通過引用傳遞'shared_ptr'而直接傳遞給'shared_ptr'的優點是什麼?」答案是:它更便宜。 – tkausl

+0

對於編譯器來說,它們都是不同的類型。你不能真正比較蘋果和橘子。 **'測試**和**'shared_ptr **不一樣*參考類型*。至於從後者獲得前者的性能成本,其可能僅僅是額外間接成本。但後者提供了更多的信息 – WhiZTiM

回答

1

原因函數應該接受一個std::shared_ptr的說法是,如果它可能需要共享或修改資源的所有權。如果不是,請不要通過std::shared_ptr

如果功能肯定需要共享所有權,那麼它應該接受值爲std::shared_ptr。如果該功能可能會或可能不會共享所有權,則只接受std::shared_ptr&

如果函數不修改所有權然後通過一個參考的資源,而不是一個std::shared_ptr

參見:CppCoreGuidelines:F.7R.30R.34R.35

0

一個用例是原始shared_ptr可以在函數中間更改其內容(可能是嵌套調用),並且函數已準備好並且需要新內容。

1

讓我們來看看你的函數中。對於initmem1,代碼通常看起來像

initMem1(myMem& mInput){ _mem1 = mInput; } 

我們可以看到一個賦值操作符,通常會將所有myMem領域的召喚。

對於initMem2,有兩種情況

1)

initMem2(shared_ptr<myMem> &pmInput){ 
    _mem2 = pmInput; 
} 

你應該用 'initMem2(常量的shared_ptr & pmInput)'。這是一個很好的風格。 我們可以在這裏看到快速初始化。只有鏈接被複制。但是你獲得了所有權共享。如果您在外面更改pmInput,則_mem2也會更改。 不需要複製cunstructor。兩個智能ptrs都擁有獨特的對象。

2)

initMem2(const shared_ptr<myMem> &pmInput){ // of course, const 
    _mem2.reset(*pmInput); 
} 

您創建新內容的新的shared_ptr最初來自pmInput複製。 您可以獨立更換pmInput_mem2。但是,對於這個新的shared_ptr和複製構造函數調用,您會獲得額外的「新/刪除調用」。