首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ Friend (友元) 機制入門:打破封裝的雙面刃

     編輯:關於C++

為何需要 Friend?

一般函式無法存取類別的 protected/private 成員。若全部設為 public,又會暴露給所有外部程式碼。friend 關鍵字允許指定函式/類別存取私有成員,在保護資料安全與提供必要存取間取得平衡。但會破壞封裝性,現代 C++ 建議慎用,優先考慮公開介面設計。

友元函式


class Internet {
public:
    Internet(char* name, char* addr) { strcpy(name_, name); strcpy(addr_, addr); }
    friend void ShowN(Internet& obj);  // 宣告友元函式
private:
    char name_[20];
    char addr_[20];
};

void ShowN(Internet& obj) {  // 定義時不加 Internet::
    cout << obj.name_ << endl;
}

void main() {
    Internet a("Lab", "www.lab.com");
    ShowN(a);  // 正常呼叫
}

注意:友元函式 不是 類別成員,定義時不可寫成 void Internet::ShowN(...)。

多類別共享友元函式


class Country;  // 前向宣告

class Internet {
    friend void ShowN(Internet&, Country&);  // 共同友元
    // ...
};

class Country {
    friend void ShowN(Internet&, Country&);  // 同一函式為兩個類別的友元
    // ...
};

void ShowN(Internet& i, Country& c) { /* 可存取兩者私有成員 */ }

成員函式作為友元


class Internet;  // 前向宣告

class Country {
public:
    void EditUrl(Internet&);  // 成員函式宣告
};

class Internet {
    friend void Country::EditUrl(Internet&);  // 指定成員函式為友元
    // ...
};

void Country::EditUrl(Internet& t) {  // 定義
    strcpy(t.addr_, "new.address");
}

友元類別 (Friend Class)


class Country {
    friend class Internet;  // 整個 Internet 類別皆為友元
    // ...
};

class Internet {
public:
    void EditCountryName(Country& c) { strcpy(c.name_, "New Name"); }  // 可存取 Country 所有私有成員
};

友元類別的所有成員函式自動成為友元,可存取對方所有私有/受保護成員。

常見用途:運算子多載

輸出運算子 operator<< 常宣告為友元,以便存取私有資料格式化輸出:


class Complex {
    friend ostream& operator<<(ostream&, const Complex&);
    // ...
};

總結

Friend 提供受控的封裝突破,適用於運算子多載、緊密協作的類別組。濫用會導致維護困難,現代 C++ 偏好透過公開介面、Getter/Setter 或組合模式解決。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved