發新話題

C++ Gossip - 物件基礎《封裝》friend 函式、friend 類別

C++ Gossip - 物件基礎《封裝》friend 函式、friend 類別

在定義類別成員時,私用成員只能被同一個類別定義的成員存取,不可以直接由外界進行存取,然而有些時候,您希望提供私用成員給某些外部函式來存取,這時您可以設定類別的「好友」,只有好友才可以直接存取自家的私用成員。

下面這個程式中使用friend關鍵字來設定類別的好友函式,該好友可以直接存取該類別的私用成員:
  • Ball.h
class Ball;

int compare(Ball&, Ball&);

class Ball {
public:
    Ball(double, char*);     
   
    double radius() {
        return _radius;
    }
   
    char* name() {
        return _name;
    }
   
    void radius(double radius) {
         _radius = radius;
    }
   
    void name(char *name) {
         _name = name;
    }
   
    // 宣告朋友函式
    friend int compare(Ball&, Ball&);
   
private:
    double _radius; // 半徑
    char *_name;  // 名稱
};
  • Ball.cpp
#include "Ball.h"

// compare 為 Ball 的 friend
int compare(Ball &b1, Ball &b2) {
    // 可直接存取私用成員
    if(b1._radius == b2._radius)
        return 0;
    else if(b1._radius > b2._radius)
        return 1;
    else
        return -1;
}

Ball::Ball(double radius, char *name) {
    _radius = radius;
    _name = name;
}

  • main.cpp
#include <iostream>
#include "Ball.h"
using namespace std;

int main() {
    Ball b1(10, "RBall");
    Ball b2(20, "GBall");
   
    switch(compare(b1, b2)) {
        case 1:
             cout << b1.name() << " 較大" << endl;
             break;
        case 0:
             cout << b1.name() << " 等於 " << b2.name() << endl;
             break;
        case -1:
             cout << b2.name() << " 較大" << endl;
             break;
    }
        
    return 0;
}
執行結果:
GBall 較大

使用friend函式通常是基於效率的考量,以直接存取私用成員而不透過函式呼叫的方式,來省去函式呼叫的負擔,另外您也可以使用friend來重載(Overload)運算子,之後的主題中會介紹。

您也可以將某個類別宣告為friend類別,被宣告為friend的類別可以直接存取私用成員,例如:
class Ball;

int compare(Ball&, Ball&);

class Ball {
public:
    ....
   
    // 宣告朋友類別
    friend class SomeClass;
   
private:
    ....
};


如上宣告的話,SomeClass的實例就可以存取Ball實例的私用成員。

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。