友元函數和友元類

1、友元介紹ios

咱們知道,類的成員函數能夠訪問同類的其餘成員函數,包括公有、私有和保護成員。而類的外部函數只能訪問類的公有成員。編程

友元是一種容許非類成員函數訪問類的非公有成員的一種機制。
能夠把一個函數指定爲類的友元,也能夠把整個類指定爲另外一個類的友元。
函數

友元函數spa

友元類設計


2、友元函數對象

友元函數在類做用域外定義,但它須要在類體中進行說明
爲了與該類的成員函數加以區別,定義的方式是在類中用關鍵字friend說明該函數,格式以下:
繼承

friend  類型 友元函數名(參數表);ci

友元的做用在於提升程序的運行效率
作用域

友元函數注意事項:io

一、友元函數不是類的成員函數,在函數體中訪問對象的成員,必須用對象名加運算符「.」加對象成員名。但友元函數能夠訪問類中的全部成員(公有的、私有的、保護的),通常函數只能訪問類中的公有成員。
二、友元函數不受類中的訪問權限關鍵字限制,能夠把它放在類的公有、私有、保護部分,但結果同樣。
三、某類的友元函數的做用域並不是該類做用域。若是該友元函數是另外一類的成員函數,則其做用域爲另外一類的做用域,不然與通常函數相同。
四、友元函數破壞了面向對象程序設計類的封裝性,因此友元函數如不是必須使用,則儘量少用。或者用其餘手段保證封裝性。

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 
#include <math.h>
#include <iostream>
using namespace std;

class Point
{
    friend double Distance(const Point &p1, const Point &p2);
public:
    Point(int x, int y);
private:

    int x_;
    int y_;
};

Point::Point(int x, int y) : x_(x), y_(y)
{

}

double Distance(const Point &p1, const Point &p2)
{
    double dx = p1.x_ - p2.x_;
    double dy = p1.y_ - p2.y_;

    return sqrt(dx * dx + dy * dy);
}

int main(void)
{
    Point p1(3, 4);
    Point p2(6, 9);

    cout << Distance(p1, p2) << endl;
    return 0;
}

程序中Distance 是Point類的友元函數,能夠訪問類的私有數據成員。


3、友元類

若是某類B的成員函數會頻繁的存取另外一個類A的數據成員, 而A的數據成員的Private/Protectd限制形成B存取的麻煩, B只能經過A的Public的成員函數進行間接存取
把B作成A類的友元類,即A類向B類開放其Private/Protectd內容, 讓B直接存取
友元類:一個類能夠做另外一個類的友元
友元類的全部成員函數都是另外一個類的友元函數
友元類的聲明:
    friend class 類名;

友元類注意事項:

一、友元關係是單向的
二、友元關係不能被傳遞
三、友元關係不能被繼承

TeleController.h :

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
#ifndef  _TELE_CONTROLLER_H_
#define _TELE_CONTROLLER_H_

class Television;

class TeleController
{
public:
    void VolumeUp(Television &tv);

    void VolumeDown(Television &tv);

    void ChanelUp(Television &tv);

    void ChanelDown(Television &tv);
};

#endif // _TELE_CONTROLLER_H_

TeleController.cpp :

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
#include "TeleController.h"
#include "Television.h"

void TeleController::VolumeUp(Television &tv)
{
    tv.volume_ += 1;
}

void TeleController::VolumeDown(Television &tv)
{
    tv.volume_ -= 1;
}

void TeleController::ChanelUp(Television &tv)
{
    tv.chanel_ += 1;
}

void TeleController::ChanelDown(Television &tv)
{
    tv.volume_ -= 1;
}

Television.h:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
#ifndef _TELEVISION_H_
#define _TELEVISION_H_

class TeleController;

class Television
{
    friend class TeleController;
public:
    Television(int volume, int chanel);
private:
    int volume_;
    int chanel_;
};

#endif // _TELEVISION_H_

Television.cpp:

 C++ Code 
1
2
3
4
5
6
 
#include "Television.h"

Television::Television(int volume, int chanel) : volume_(volume), chanel_(chanel)
{

}

main.cpp:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
#include "Television.h"
#include "TeleController.h"
#include <iostream>
using namespace std;


int main(void)
{
    Television tv(1, 1);

    TeleController tc;
    tc.VolumeUp(tv);

    return 0;
}

TeleController 類做爲Television類的友元類,這樣TeleController 類的成員函數就均可以訪問Television類的全部成員,包括私有。


參考:

C++ primer 第四版 Effective C++ 3rd C++編程規範

相關文章