C++規定有四個運算子 =, ->, [], ()不可以是全域域中的重載(即不能重載為友員函數)理解。__Jquery

來源:互聯網
上載者:User
以下是對C++中不能重載為友元函數的四個運算子進行了詳細的分析介紹,需要的朋友可以過來參考下  

C++規定有四個運算子 =, ->, [], ()不可以是全域域中的重載(即不能重載為友員函數),這是為什麼呢。
現在先說說賦值運算子“=”的重載
C++規定賦值運算子“=”只能重載為類的非靜態成員函數,而不可以重載為類的友元函數。
不能重載為類的靜態成員應該比較容易理解,因為靜態成員函數是屬於整個類的,不是屬於某個對象的,它只能去操作類待用資料成員。而賦值運算子“=”是基於對象操作的。
那麼為什麼賦值運算子不可以重載為類的友元函數。像同樣都是雙目運算子的+為什麼它就可以呢。

在討論這問題之前,先看一測試的程式:
複製代碼 代碼如下:
#include <iostream>
using namespace std;

class A
{
private:

  int x;
public:
         A(){x=99;}
         A(int xx)
         {
                   cout<<"Call A(int xx)"<<endl;
                   x = xx;
         }
};
int main()
{
         A a;
         a = 7;
}


程式執行結果為:
Call A(int xx)

說明執行a = 7這程式語句時,程式去調用類A中的帶參建構函式。
在類A中加入一賦值運算重載成員函數,如下: 複製代碼 代碼如下:
#include <iostream>
using namespace std;

class A
{
private:
         int x;
public:
         A(){x=99;}
         A(int xx)
         {
                   cout<<"Call A(int xx)"<<endl;
                   x = xx;
         }
         A operator=(int xx)   //重載賦值運算子運算
         {
                   cout<<"Call A operator=(int xx)"<<endl;
                   x = xx;
                   return *this;
         }
};

int main()
{
         A a;
         a = 7;
}


程式運行結果:
Call A operator=(int xx)

說明在類A中已經有相應賦值運算子多載函數的時候,執行指派陳述式a = 7;程式會去調用類A中相應的賦值運算子多載函數,而不會像上面原來那樣去調用有參建構函式。

在此,我們可以對C++規則做出以下的判斷:
當 類中沒有定義賦值運算子多載成員函數時(注意,在未定義形參資料類型為該類類型的賦值運算子多載函數時,編譯器會自動產生加入),當程式執行到某一賦值語 句時,程式就會調用與指派陳述式中右實值型別匹配的建構函式,而把這右值當作此建構函式的實參。像最初的指派陳述式a = 7,執行時,實際做的操作是a(7)。而當類中有定義賦值運算子多載成員函數,執行指派陳述式時,程式就只會去調用相應的賦值運算子多載函數。 

當明白上面的規則後,現在就可以回過來,討論為什麼賦值運算子不可以重載為類的友元函數了。

我們知道友元函數不是類的成員函數,它只是類的“朋友“,具有訪問把它聲明為“朋友”的類的資料成員的許可權而已。
那麼當把賦值運算子多載為類的友員函數,在程式中執行類對象的指派陳述式時,程式就會出現兩種矛盾的選擇。

1、因為它認為類中並沒有重載賦值運算子的成員函數,所以它根據C++的規則,會去調用相應的建構函式。

2、但是在全域裡,我們已經重載了參數類型為此類類型的賦值運算子函數,而這指派陳述式剛好和這函數匹配上了,根據C++的規則,也會去調用這函數。

程式是不允許有矛盾不確定選擇的,所以當賦值運算子多載為類的友元函數時,編譯器就會提示錯誤。

對於剩下的3個運算子 ->, [], () 為什麼不能重載為友元函數,也是跟上面一樣的道理。即編譯器發現當類中沒有定義這3個運算子的重載成員函數時,就會自己加入預設的運算子多載成員函數。
例當類A中沒有定義運算子->的重載成員函數,但是我們仍然可以對類A對象指標用->的形式調用指標指向的對象裡的成員。像類A裡有成員函數f(),當 複製代碼 代碼如下:
A a;
A* p = &a;
 p->f();   //雖然類A中沒有自己定義運算子->重載成員函數,但這裡仍可這樣使用


然而,當我們把->運算子多載為類A的友元函數時,程式就會出現跟把賦值運算子多載友元一樣的情況,即產生矛盾性。


總結來說,這幾個運算子不能重載為友元函數的原因就是,C++一個類本身對這幾個運算子已經有相應的解釋了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.