我剛纔所讀經典書「有效的C++,第3版」,並在第20項筆者的結論是,內置類型,STL的迭代器和函數對象種類較多,適合傳遞價值。我可以很好理解內建和迭代器類型的原因,但爲什麼要函數對象被傳遞由值,因爲我們知道這是無論如何類類型?爲什麼函數對象應該是通過按值
回答
在典型的情況下,一個功能對象將有很少或(更通常)沒有持久狀態。在這種情況下,通過價值傳遞可能不需要實際傳遞任何東西 - 傳遞的「價值」基本上只是「這是對象」的佔位符。
由於許多函數對象中的代碼量很少,導致進一步優化:編譯器通常很容易擴展函數對象的內聯代碼,因此沒有參數傳遞,並且沒有函數調用參與其中。
編譯器可以能夠當你通過指針或引用,而不是做同樣的,但它不是那麼容易 - 很多比較常見的,你會與對象最終被創建的,其地址傳遞,然後通過該指針調用該對象的函數調用操作符。
編輯:這可能也是值得一提的是,同樣適用於lambda表達式,因爲他們真的只是功能僞裝對象。你不知道類的名字,但是他們在緊鄰的作用域中創建一個類,它重載了函數調用操作符,當你「調用」lambda時被調用。 [感謝@馬克西亞。]
感謝您的解釋,「內聯優化」部分讓我印象深刻。 – JavaBeta
我的工作經驗表明,廣泛使用'boost :: bind'會導致複製的代價很高的函數對象。這似乎成倍增加綁定深度(結合具有結合內部等回調回調) –
從有效的STL(因爲你看起來很喜歡斯科特·邁耶斯)第38項設計仿函數類用於傳遞值。
「在C和C++中,函數指針都是按值傳遞的,STL函數對象是在函數指針之後建模的,所以STL中的約定是,函數對象也是在函數傳遞時通過值傳遞的。 「編輯器可以做一些優化,比如內聯代碼以避免函數調用(你必須將你的函數標記爲內聯),這有一些好處和一些暗示,像@Jerry Coffin說的。這種情況的一個很好的例子是qsort vs std :: sort性能比較,其中std :: sort使用內聯函數的性能比qsort大很多,你可以在有效的STL中找到更多關於這方面的信息,這在廣泛討論並在幾個章節。
這也有一些暗示,因爲函數對象是通過值並返回的,所以您必須確保您的對象具有定義良好的複製機制,體積小(否則可能會變得昂貴),並且是單形的(因爲按值傳遞多態對象可能會導致對象切片)。
邁爾斯的有效串聯是在中國很受歡迎:-)。另外,感謝std :: sort和std :: qsort之間的區別。 – JavaBeta
#1原因按值傳遞函數對象是因爲標準庫需要函數對象傳遞給它的算法,可拷貝。 C++ 11§25.1/ 10:
[注:除非另有規定,即採取函數對象作爲參數被允許的算法複製 那些功能自由對象。對他們來說,程序員對象的身份是很重要的應該考慮使用一個指向noncopied實施對象,如
reference_wrapper<T>
(20.8.3), 或某些等效解決方案 包裝類。 - 注意]
其他答案做了很好的解釋理由。
- 1. 模型和數據訪問對象,應該通過,應該通過什麼
- 2. 爲什麼我們應該總是從函數返回值?
- 3. 爲什麼我應該模擬對象?
- 4. 實體,價值對象還是它應該是什麼?
- 5. 什麼應該是構造函數屬性值..a原型構造函數或對象構造函數本身
- 6. 按前綴過濾數組 - 該函數的名稱是什麼?
- 7. 爲什麼按值傳遞一個對象即使該對象沒有拷貝構造函數也能工作?
- 8. 通過函數訪問對象值
- 9. 對象值通過C++函數
- 10. 原生$函數應該是什麼?
- 11. dummy()函數 - 這應該是什麼?
- 12. 爲什麼mvc無法通過對象
- 13. Perl:「validate」函數中類對象應該使用什麼類型
- 14. 爲什麼cppcheck說「函數參數應該通過引用傳遞」?
- 15. 通過對象不是值
- 16. 應該是什麼,我可以在XML通過除X爲CHECKBOXTYPE
- 17. 什麼行爲應該是測試的對象?
- 18. lambda函數C++通過值捕獲重置其值,爲什麼?
- 19. 什麼是對象構造函數?
- 20. 爲什麼對象類不是空值
- 21. 爲什麼我們無法通過jquery獲取對象值
- 22. 爲什麼數組的對象屬性正確訪問該值?
- 23. 爲什麼我們應該在全局函數/對象上使用「::」運算符?
- 24. javascript如果函數是對象,那麼爲什麼不工作
- 25. 從函數返回大對象:通過值VS通過指針
- 26. 我應該通過什麼作爲參數?
- 27. 什麼時候應該通過一個類作爲參數?
- 28. 從函數中通過引用獲取對象,而不是值
- 29. C++爲什麼變量是函數而不是對象?
- 30. 爲什麼Math是一個對象而String是一個函數?
+1看了C++有效 – Borgleader
函數對象應該很少有多大的開銷。 – chris
至少,現在有更多的邏輯(所有對象,一般)都有移動語義。 –