程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> 解析C++中不能重載為友元函數的四個運算符

解析C++中不能重載為友元函數的四個運算符

編輯:更多關於編程
    以下是對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的友元函數時,程序就會出現跟把賦值運算符重載友元一樣的情況,即產生矛盾性。
    聲明:以上僅為個人見解

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved