C++關鍵字之friend


      原則上, 類的私有(private)和受保護(protected)成員不能從聲明它們的同一類外部訪問。但是, 此規則不適用於友元 "friends"。

      以friend關鍵字修飾的函數或類稱為友元函數或友元類。

友元函數

       友元函數是可以直接訪問類的私有成員的非成員函數。它是定義在類外的普通函數,它不屬於任何類,但需要在類的定義中加以聲明,聲明時只需在友元的名稱前加上關鍵字friend,其格式如下:

     friend 類型 函數名(形式參數);

  友元函數的聲明可以放在類的私有部分,也可以放在公有部分,它們是沒有區別的,都說明是該類的一個友元函數。

  一個函數可以是多個類的友元函數,只需要在各個類中分別聲明。

  友元函數的調用與一般函數的調用方式和原理一致。

 

友元類

  友元類的所有成員函數都是另一個類的友元函數,都可以訪問另一個類中的隱藏信息(包括私有成員和保護成員)。       

  當希望一個類可以存取另一個類的私有成員時,可以將該類聲明為另一類的友元類。定義友元類的語句格式如下:

  friend class 類名;

  其中:friend和class是關鍵字,類名必須是程序中的一個已定義過的類。

 

綜合例子

#include <iostream>
using namespace std;

class Square;
class Rectangle 
{
private:
    int m_nWidth;
    int m_nHeight;

public:
    Rectangle() {}
    Rectangle (int nX, int nY) : m_nWidth(nX), m_nHeight(nY) {}
    int area() {return m_nWidth * m_nHeight;}
    friend Rectangle duplicate (const Rectangle&);   // friend functions
    void convert (Square a);
};

Rectangle duplicate (const Rectangle& param)
{
    Rectangle res;
    res.m_nWidth = param.m_nWidth*2;
    res.m_nHeight = param.m_nHeight*2;
    return res;
}

class Square 
{
    friend class Rectangle;                            // friend class
private:
    int side;
public:
    Square (int a) : side(a) {}
};

void Rectangle::convert (Square a) 
{
    m_nWidth = a.side;
    m_nHeight = a.side;
}

int main () {
    Rectangle foo;
    Rectangle bar (2,3);
    foo = duplicate (bar);
    cout << foo.area() << endl;

    Rectangle rect;
    Square sqr (4);
    rect.convert(sqr);
    cout << rect.area() << endl;

    return 0;
}

  說明

  duplicate 函數為類Rectangle的一個友元函數,可以訪問該類的不同對象的私有成員m_nWidth和m_nHeight,形式上看duplicate 聲明為該類的一個成員函數,但是其僅僅有該類私有成員的訪問權限而已,並不是該類的一個成員函數!

  類Rectangle為類Square 的一個友元類,則允許類Rectangle的成員函數可以訪問類Square 的私有或保護成員,本例中訪問了類Square 的私有成員變量side。

 

使用友元類時注意

  1、友元關系不能被繼承。

  2、友元關系是單向的,不具有交換性。若類B是類A的友元,類A不一定是類B的友元,要看在類中是否有相應的聲明。

  3、友元關系具有非傳遞性。若類B是類A的友元,類C是B的友元,類C不一定是類A的友元,同樣要看類中是否有相應的申明。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM