文章目錄
- 1.友元
- 1.什么是友元
- 2.全局函數做友元
- 2.類做友元
- 3.成員函數做友元
1.友元
1.什么是友元
在C++中,友元(friend)是一種允許一個類或函數訪問另一個類的非公有(private 或 protected)成員的機制。這種機制打破了類的封裝性,因此在使用時需要謹慎。然而,在某些情況下,友元提供了一種方便的方式來實現特定的功能,如操作符重載、輸入輸出流操作等。
友元可以是另一個類、類的成員函數、或者全局函數。當一個類或函數被聲明為另一個類的友元時,它就可以訪問那個類的所有私有和保護成員。
2.全局函數做友元
全局函數(非類成員函數)也可以被聲明為類的友元。這樣做允許全局函數訪問類的私有(private
)和保護(protected
)成員。
#include <iostream>class MyClass {// 聲明全局函數 friendFunc 為友元friend void friendFunc(MyClass& obj);private:int secretValue;public:MyClass(int value) : secretValue(value) {}
};// 全局函數,它可以訪問 MyClass 的私有成員
void friendFunc(MyClass& obj) {std::cout << "Secret value: " << obj.secretValue << std::endl;
}int main() {MyClass myObj(42);friendFunc(myObj); // 輸出: Secret value: 42return 0;
}
在這個例子中,friendFunc
是一個全局函數,它被聲明為 MyClass
的友元。因此,friendFunc
可以訪問 MyClass
的私有成員 secretValue
。在 main
函數中,我們創建了一個 MyClass
對象 myObj
,并將其傳遞給 friendFunc
,后者成功輸出了 secretValue
的值。
2.類做友元
在C++中,一個類也可以被聲明為另一個類的友元。當一個類被聲明為另一個類的友元時,這個友元類可以訪問另一個類的私有(private
)和保護(protected
)成員。這種機制在某些情況下可能很有用,特別是當兩個類需要緊密協作,并且一個類需要直接訪問另一個類的內部數據時。
#include <iostream>class MyClass {// 聲明另一個類(例如 MyFriendClass)為友元friend class MyFriendClass;private:int secretValue;public:MyClass(int value) : secretValue(value) {}// 提供一個公共函數以顯示secretValue的值(僅用于比較)void displaySecretValue() const {std::cout << "Secret value: " << secretValue << std::endl;}
};// 友元類 MyFriendClass
class MyFriendClass {
public:// MyFriendClass 可以訪問 MyClass 的私有成員void printSecret(const MyClass& obj) {std::cout << "MyFriendClass sees: " << obj.secretValue << std::endl;}
};int main() {MyClass myObj(42);MyFriendClass friendObj;// 通過 MyClass 的公共函數顯示 secretValuemyObj.displaySecretValue(); // 輸出: Secret value: 42// 通過 MyFriendClass 訪問 MyClass 的私有成員friendObj.printSecret(myObj); // 輸出: MyFriendClass sees: 42return 0;
}
在這個例子中,MyFriendClass
被聲明為 MyClass
的友元。因此,MyFriendClass
中的成員函數 printSecret
可以訪問 MyClass
對象的 secretValue
成員,即使它是私有的。注意,友元關系不是雙向的;即 MyClass
不是 MyFriendClass
的友元,除非另外聲明。
使用類作為友元時要特別小心,因為它破壞了封裝性,并可能導致代碼難以維護和理解。在可能的情況下,最好使用公共接口和受保護的成員來實現類之間的協作。然而,在某些情況下,類作為友元可能是實現特定功能所必需的。
3.成員函數做友元
在C++中,成員函數本身并不直接作為另一個類的友元,因為成員函數是類的一部分,它總是能夠訪問其所在類的所有成員(包括私有和保護成員)。然而,你可以將一個類的成員函數聲明為另一個類的友元,但實際上是將這個成員函數所屬的整個類聲明為友元。
但如果你想讓另一個類的成員函數能夠訪問當前類的私有或保護成員,你應該做的是將該成員函數所在的整個類聲明為當前類的友元。
#include <iostream>class MyClass {// 聲明另一個類(例如 OtherClass)為友元friend class OtherClass;private:int secretValue;public:MyClass(int value) : secretValue(value) {}// 提供一個公共函數以顯示secretValue的值(僅用于比較)void displaySecretValue() const {std::cout << "Secret value: " << secretValue << std::endl;}
};class OtherClass {
public:// 這個成員函數可以訪問 MyClass 的私有成員void printSecret(const MyClass& obj) {std::cout << "OtherClass sees: " << obj.secretValue << std::endl;}
};int main() {MyClass myObj(42);OtherClass friendObj;// 通過 MyClass 的公共函數顯示 secretValuemyObj.displaySecretValue(); // 輸出: Secret value: 42// 通過 OtherClass 的成員函數訪問 MyClass 的私有成員friendObj.printSecret(myObj); // 輸出: OtherClass sees: 42return 0;
}
在這個例子中,OtherClass
被聲明為 MyClass
的友元,這意味著 OtherClass
的所有成員函數(不僅僅是 printSecret
)都可以訪問 MyClass
的私有成員。然而,在實際編程中,通常最好只將真正需要訪問私有成員的成員函數所在的類聲明為友元,以保持封裝的完整性。
//
// Created by 86189 on 2024/6/6.
//
#include "iostream"
using namespace std;class myClassFriend;
class myClass{
public:myClass();void visit();myClassFriend *myClassfriend;
};
class myClassFriend{friend void myClass::visit();;
public:myClassFriend();
public:string name;
private:string sex;
};myClassFriend::myClassFriend() {name = "張三";sex = "男";
}myClass::myClass() {myClassfriend = new myClassFriend;
}void myClass::visit() {cout << myClassfriend->name << endl;cout << myClassfriend->sex << endl;
}int main() {myClass myclass;myclass.visit();delete myclass.myClassfriend;return 0;
}
只通過成員函數訪問另一個類的私有成員。