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

C++ 友元函數與友元類完整解析:打破封裝的特權訪問

     編輯:關於C++

C++ 友元函數與友元類完整解析

類的私有成員默認不可被外部訪問。friend 關鍵字授予特定函數或類「友元」身份,可直接訪問私有/保護成員。破壞封裝,慎用。

友元函數

class Point {
    double x, y;
public:
    Point(double a, double b) : x(a), y(b) {}
    friend double Distance(const Point&, const Point&); // 類內聲明
};

double Distance(const Point& a, const Point& b) {
    double dx = a.x - b.x; // 直接訪問私有成員
    double dy = a.y - b.y;
    return sqrt(dx*dx + dy*dy);
}

特點

  • 類內聲明加 friend,類外定義不加
  • 非成員函數,調用如普通函數
  • 可訪問所有私有/保護成員
  • 不屬於類作用域,無 this 指標

友元類

class A {
    int x; static int y;
    friend class B; // 整個 B 類是 A 的友元
public:
    void set(int v) { x = v; }
    void show() { cout << "x=" << x << ", y=" << y << endl; }
};

class B {
    A a;
public:
    B(int i, int j) { a.x = i; A::y = j; } // 訪問 A 的私有靜態成員
    void show() { cout << "x=" << a.x << ", y=" << A::y << endl; }
};

關鍵行為

  • 友元關係單向:B 是 A 友元 ⇒ B 可訪問 A 私有,反之不成立
  • 不傳遞:B 是 A 友元,C 繼承 B ⇒ C 不是 A 友元
  • 靜態成員屬於類,友元類可直接用 類名::靜態成員 訪問

完整演示程式碼

#include <iostream>
using namespace std;

class Base {
    int a1; protected: int a2; private: int a3;
public:
    friend void friend_func(Base&);
    friend class FriendClass;
};

void friend_func(Base& b) {
    b.a1 = 1; b.a2 = 2; b.a3 = 3; // 全部可訪問
}

class FriendClass {
    Base b;
public:
    void test() { b.a1=10; b.a2=20; b.a3=30; }
};

int main() {
    Base obj;
    friend_func(obj);
    FriendClass fc; fc.test();
    return 0;
}

最佳實務建議

  1. 優先用公有介面:提供 getter/setter 而非友元
  2. 運算子重載:operator<<, operator+ 等需訪問私有時常用友元
  3. 工廠/建構者模式:特定創建類需訪問私有建構函數
  4. 避免濫用:友元增加耦合,破壞封裝,維護困難
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved