有人可以請示例解釋爲什麼在C++中重載逗號,地址,邏輯和和邏輯OR運算符不是一個好習慣嗎?爲什麼逗號,地址 - ,邏輯AND和邏輯OR運算符不應該在C++中重載?
回答
如果有人讀取代碼並看到if(a && b)
,他/她會怎麼想?
如果a和b是原生類型,如bool
或int
,則每個人都知道它是如何工作的。
如果它們是類對象,大多數人會希望在應用&&
之前,該類提供了一個operator bool()
或類似的查詢它應該是什麼bool。沒有人會認爲這是一種「幻想」的方式來編寫if(a.myMethod(b))
,沒有人願意檢查類定義=>每個人都會誤解和/或混淆狀態的目的是什麼。
tldr,請勿將內置的&&
用作無關方法調用的縮寫。
同樣是有效的||
和,
。
至於地址運算符,除了讀取混淆問題之外,在編寫代碼時也很常見:指針地址通常可以爲任何類型的變量獲取,並且在執行此操作之前,沒有人會檢查您的類定義。
而且可讀性等等,如果以什麼順序的參數賦值不同:
爲if(a&&b)
正常,如果是false
,b
甚至沒有檢查了,因爲整個條件只能是假。如果你有像例如。 if(a && func1()) func2();
其中返回值func2()
很重要,func1()
被執行只有如果a
是true
,並且只有兩者都爲真時纔會執行func2()
。超載&&
,func1()
爲總是執行。取決於它的作用,這可能不是你想要的。
隨着||
,這是類似的:如果第一個參數是true
,第二個參數通常不會看着了,因爲整個條件爲真,反正。有了過載,參數總是被評估。
正常的逗號運算符a,b
有保證a
在b
之前被評估/執行;過載時可以按任何順序。
代碼可讀性是一個問題。但是如果你檢查這個鏈接https://www.securecoding.cert.org/confluence/display/cplusplus/DCL10-CPP.+Do+not+overload+the+ampersand,+comma,+logical+AND+or+logical + OR +操作符,這裏解釋的原因對我來說很難理解。所以,我問了這個現在被低估的問題。 – bornfree
@bornfree我不是在說可讀性。 ...關於您的鏈接,我將補充說明...... – deviantfan
潛在的原因是這些運算符的重載版本的行爲與內建版本的行爲不同。這會導致(人類)閱讀/編寫代碼的實質性混亂。
邏輯運算符
&&
和||
的內置版本呈現短路優化:在像a && b
一個表達式,a
首先計算且僅當true
,b
還評價;類似地,在a || b
,a
中首先被評估,並且只有在false
,b
也被評估。重載運算符&&
和||
沒有短路優化(總是對a
和b
進行評估),也未指定參數計算的順序。逗號運算符的內置版本保證參數在它們發生的順序,即,在評價
a,b
a
首先計算然後b
。在重載逗號運算符的情況下,這個保證將會丟失(而函數參數機制會發揮作用)。地址運算符有內建地址運算符
&
並且當應用於不完整的類型的對象重載一個之間的潛在的混淆。考慮以下代碼struct type; // forward declaration: type is (as of yet) incomplete #include <memory> void foo(type &obj) // allowed: take object of incomplete type by reference { auto ptr1 = &obj; // address of obj -- or not? auto ptr2 = std::addressof(obj); // always address of obj } // possibly in a different translation unit: struct type { type* operator&() { return nullptr; } };
該代碼具有unspecified behaviour:編譯器可以在
foo()
實現無論是&
運營商的版本,但人寫的foo()
代碼無法知道這或運營商將被使用。 使用std::addressof
與ptr2
相比可以避免此問題,即使type
運算符有重載&
,該問題也會獲得內建運算符地址的等效值。
根據[CWG1458](http://wg21.link/CWG1458),'運營商&案例現在未指定。 –
謝謝@ T.C。將修改我的答案 – Walter
- 1. C++運算符重載邏輯opertors
- 2. 邏輯運算符Objective-C
- 3. 邏輯運算符
- 4. C++邏輯運算符Q
- 5. 邏輯運算符
- 6. 邏輯運算符||
- 7. 重載邏輯運算符被認爲是不好的做法?
- 8. 邏輯&&運算符
- 9. 邏輯運算
- 10. 什麼是NOR邏輯運算符?
- 11. Spring SpEL邏輯運算符
- 12. 如何有多個「和」邏輯運算符和「或」邏輯運算符
- 13. 邏輯AND運算符
- 14. C++邏輯與運算
- 15. Java邏輯運算符
- 16. 邏輯比較運算符
- 17. 結合邏輯運算符C
- 18. C#中邏輯運算符的結構#
- 19. 2列的邏輯運算(邏輯或)
- 20. C# - 解析包含邏輯運算符
- 21. 邏輯與運算符與
- 22. 爲什麼C沒有邏輯賦值運算符?
- 23. 邏輯和虛擬地址
- 24. 使用(邏輯):運算符C#
- 25. 邏輯比較==運算符過載
- 26. 不同的邏輯地址
- 27. PowerShell邏輯運算符和$ Error變量
- 28. 重載運算符C++的邏輯錯誤
- 29. 被C++邏輯OR(||)運算符困惑
- 30. ATT裝配(算術和邏輯運算)
如果您重載了逗號運算符,那麼您就是STL將其C++ STL實現更改爲在適當情況下執行'a,void(),b'的原因。 – chris
我不認爲這個問題應該被視爲'主要基於意見' – Walter
誰說的和什麼時候? –