大多數的運算符能夠被程序員重載。例外的是:
. (點符號) :: ?: sizeof
并沒有什么根本的原因要禁止重載?:。僅僅是因為,我沒有發現有哪種特殊的情況需要重載一個三元運算符。注意一個重載了 表達式1?表達式2:表達式3 的函數,不能夠保證表達式2:表達式3 中只有一個會被執行。
Sizeof 不能夠被重載是因為內建的操作(built-in operations),諸如對一個指向數組的指針進行增量操作,必須依靠它??紤]一下:
X a[10]; X* p = &a[3]; X* q = &a[3]; p++; // p 指向a[4] // 那么p 的整型值必須比q 的整型值大出一個sizeof(X)
所以,sizeof(X)不能由程序員來賦予一個不同的新意義,以免違反基本的語法。
在N::m 中,無論N 還是m 都不是值的表達式;N 和m 是編譯器知道的名字,::執行一個(編譯期的)范圍解析,而不是表達式求值。你可以想象一下,允許重載x::y 的話,x 可能是一個對象而不是一個名字空間(namespace)或者一個類,這樣就會導致——與原來的表現相反——產生新的語法(允許 表達式1::表達式2)。很明顯,這種復雜性不會帶來任何好處。
理論上來說,.(點運算符)可以通過使用和->一樣的技術來進行重載。但是,這樣做會導致一個問題,那就是無法確定操作的是重載了.的對象呢,還是通過.引用的一個對象。例如:
class Y { public: void f(); // ...};class X { // 假設你能重載. Y* p; Y& operator.() { return *p; } void f(); // ...};void g(X& x){ x.f(); // X::f 還是Y::f 還是錯誤?}
附上C++重載的一些總結
重載操作符的限制:
1 并不是所有的操作符都能被重載。除了. ,.* ,:: ,? : ,sizeof,typeid這幾個運算符不能被重載,其他運算符都能被重載
2 重載不能改變該運算符用于內置類型時的函義,程序員不能改變運算符+用于兩個int型時的含義。
3 運算符函數的參數至少有一個必須是類的對象或者類的對象的引用。這種規定可以防止程序員運用運算符改變內置類型的函義。
4 重載不能改變運算符的優先級。
5 重載不能改變運算符的結合律。
6 重載不能改變運算符操作數的個數。比如+需要兩個操作數,則重載的+也必須要有兩個操作數。