成員函數(shù)重載運(yùn)算符和友元函數(shù)重載運(yùn)算符

先上題:下列運(yùn)算符都可以被友元函數(shù)重載的是:
A) =,+,-,
B) [],+,(),new
C) ->,+,,>>
D) <<,>>,+,

正確答案為D

在運(yùn)算符重載,友元函數(shù)運(yùn)算符重載函數(shù)與成員運(yùn)算符重載函數(shù)的區(qū)別是:友元函數(shù)沒有this指針,而成員函數(shù)有,因此,在兩個(gè)操作數(shù)的重載中友元函數(shù)有兩個(gè)參數(shù),而成員函數(shù)只有一個(gè)。

重載運(yùn)算符的基本原則:

  1. 為了防止用戶對(duì)標(biāo)準(zhǔn)類型進(jìn)行運(yùn)算符重載,C++規(guī)定重載后的運(yùn)算符的操作對(duì)象必須至少有一個(gè)是用戶定義的類型
    比如說現(xiàn)在有兩個(gè)數(shù):int number1,int number2,
    那么number1+number2 求的是兩個(gè)數(shù)的和,
    但是如果你重載以后讓著兩個(gè)數(shù)相加為他們的乘積,這肯定是不合乎邏輯的。
    可能重載以后會(huì)有二義性,導(dǎo)致程序不知道該執(zhí)行哪一個(gè)(是自帶的的還是重載后的函數(shù))
  2. 使用運(yùn)算符不能違法運(yùn)算符原來的句法規(guī)則。如不能將% 重載為一個(gè)操作數(shù)
  3. 不能修改運(yùn)算符原先的優(yōu)先級(jí)
  4. 不能創(chuàng)建一個(gè)新的運(yùn)算符,例如不能定義operator** (···)來表示求冪
  5. 不能進(jìn)行重載的運(yùn)算符
    .:成員訪問運(yùn)算符
    ., ->:成員指針訪問運(yùn)算符
    :::域運(yùn)算符
    sizeof:長(zhǎng)度運(yùn)算符
    ?::條件運(yùn)算符
    #: 預(yù)處理符號(hào)

下面比較成員函數(shù)和非成員函數(shù)(友元函數(shù))重載運(yùn)算符

  1. 對(duì)雙目運(yùn)算符而言,成員函數(shù)重載運(yùn)算符的函數(shù)參數(shù)表中只有一個(gè)參數(shù),而用友元函數(shù)重載運(yùn)算符函數(shù)參數(shù)表中含有兩個(gè)參數(shù)。
    對(duì)單目運(yùn)算符來說,成員函數(shù)重載運(yùn)算符的函數(shù)參數(shù)表中沒有參數(shù),而用友元函數(shù)重載運(yùn)算符函數(shù)參數(shù)表中含有一個(gè)函數(shù)。這個(gè)問題要搞清楚,有一個(gè)this指針的問題
  2. 雙目運(yùn)算符一般可以用友元函數(shù)重載和成員函數(shù)重載,但有一種情況只可以用友元函數(shù)重載。
    即:雙目運(yùn)算符左邊的變量是一個(gè)常量,而不是對(duì)象!??!這點(diǎn)很重要的額。比如說string,左邊是一個(gè)const char*
    string str = "test";
    string ok = "testtest" + str;
    //這樣的運(yùn)算符必須是友元,因?yàn)樗牡谝粋€(gè)參數(shù)是char* 類型,相當(dāng)于調(diào)用 operator (char , string str)
    string oook = str + "testset"; //這個(gè)就必須是成員函數(shù),因?yàn)榈谝粋€(gè)str+ 表示調(diào)用str的成員函數(shù)operator+(char
    )

所以說,單目運(yùn)算符建議選擇成員函數(shù)。

下面是重點(diǎn)

只能作為成員函數(shù)重載的四個(gè)操作符

=,(),[],->
原因很簡(jiǎn)單,會(huì)和編譯器默認(rèn)分配的運(yùn)算符重載成員函數(shù)沖突,引發(fā)歧義。
我們知道友元函數(shù)不是類的成員函數(shù),它只是類的“朋友“,具有訪問把它聲明為“朋友”的類的數(shù)據(jù)成員的權(quán)限而已。
那么當(dāng)把賦值運(yùn)算符重載為類的友員函數(shù),在程序中執(zhí)行類對(duì)象的賦值語(yǔ)句時(shí),程序就會(huì)出現(xiàn)兩種矛盾的選擇。

  1. 因?yàn)樗J(rèn)為類中并沒有重載賦值運(yùn)算符的成員函數(shù),所以它根據(jù)C++的規(guī)則,會(huì)去調(diào)用相應(yīng)的構(gòu)造函數(shù)。
  2. 但是在全局里,我們已經(jīng)重載了參數(shù)類型為此類類型的賦值運(yùn)算符函數(shù),而這賦值語(yǔ)句剛好和這函數(shù)匹配上了,根據(jù)C++的規(guī)則,也會(huì)去調(diào)用這函數(shù)。

程序是不允許有矛盾不確定選擇的,所以當(dāng)賦值運(yùn)算符重載為類的友元函數(shù)時(shí),編譯器就會(huì)提示錯(cuò)誤。
對(duì)于剩下的3個(gè)運(yùn)算符 ->, [], () 為什么不能重載為友元函數(shù),也是跟上面一樣的道理。即編譯器發(fā)現(xiàn)當(dāng)類中沒有定義這3個(gè)運(yùn)算符的重載成員函數(shù)時(shí),就會(huì)自己加入默認(rèn)的運(yùn)算符重載成員函數(shù)。

那么下面這個(gè)題的答案也就很明顯了:
將x+y*z中的“+”用成員函數(shù)重載,“*”用友元函數(shù)重載應(yīng)該寫為:?
答案為:x.operator+(operator*(y,z))

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • C++運(yùn)算符重載-下篇 本章內(nèi)容:1. 運(yùn)算符重載的概述2. 重載算術(shù)運(yùn)算符3. 重載按位運(yùn)算符和二元邏輯運(yùn)算符4...
    Haley_2013閱讀 1,522評(píng)論 0 49
  • C++運(yùn)算符重載-上篇 本章內(nèi)容:1. 運(yùn)算符重載的概述2. 重載算術(shù)運(yùn)算符3. 重載按位運(yùn)算符和二元邏輯運(yùn)算符4...
    Haley_2013閱讀 2,385評(píng)論 0 51
  • 第2章 基本語(yǔ)法 2.1 概述 基本句法和變量 語(yǔ)句 JavaScript程序的執(zhí)行單位為行(line),也就是一...
    悟名先生閱讀 4,542評(píng)論 0 13
  • 小時(shí)候 孤獨(dú)是迷藏游戲 你找不到我我找不到你 長(zhǎng)大后 孤獨(dú)如下象棋 半天一步大家早已離去 現(xiàn)在呀 孤獨(dú)塞進(jìn)了手機(jī) ...
    yangxian_阿泱閱讀 283評(píng)論 11 9
  • 引言 世上本沒有路,走的人多了便成了路。軟件本沒有什么設(shè)計(jì)模式,一個(gè)問題的解決方案使用的人和次數(shù)多了便成為了某一種...
    sxyxsp123閱讀 500評(píng)論 0 3

友情鏈接更多精彩內(nèi)容