详细介绍c++中的友元函数和友元类
在 C++ 中,友元(Friend) 是一种特殊的机制,允许某个函数或类访问另一个类的私有(private
)和保护(protected
)成员。友元打破了类的封装性,但在某些情况下非常有用,例如需要实现某些特殊功能或优化性能时。
1. 友元函数(Friend Function)
友元函数是一个非成员函数,但它可以访问类的私有和保护成员。友元函数需要在类内声明,并使用 friend
关键字。
1.1 声明友元函数
在类中声明友元函数的语法如下:
class MyClass {
private:
int privateData;
public:
MyClass(int data) : privateData(data) {}
// 声明友元函数
friend void showPrivateData(const MyClass& obj);
};
// 定义友元函数
void showPrivateData(const MyClass& obj) {
std::cout << "Private data: " << obj.privateData << std::endl;
}
1.2 使用友元函数
友元函数可以直接访问类的私有成员:
int main() {
MyClass obj(42);
showPrivateData(obj); // 输出: Private data: 42
return 0;
}
1.3 特点
1.友元函数不是类的成员函数,因此没有 this
指针。
2.友元函数可以定义在类的任何部分(private
、protected
或 public
),但通常放在类的开头。
3.友元函数可以访问多个类的私有成员(如果被声明为多个类的友元)。
2. 友元类(Friend Class)
友元类是一个类,它可以访问另一个类的私有和保护成员。友元类需要在目标类中声明,并使用 friend
关键字。
2.1 声明友元类
在类中声明友元类的语法如下:
class MyClass {
private:
int privateData;
public:
MyClass(int data) : privateData(data) {}
// 声明友元类
friend class FriendClass;
};
class FriendClass {
public:
void showPrivateData(const MyClass& obj) {
std::cout << "Private data: " << obj.privateData << std::endl;
}
};
2.2 使用友元类
友元类可以访问目标类的私有成员:
int main() {
MyClass obj(42);
FriendClass friendObj;
friendObj.showPrivateData(obj); // 输出: Private data: 42
return 0;
}
2.3 特点
1.友元类的所有成员函数都可以访问目标类的私有和保护成员。
2.友元关系是单向的。如果 A
是 B
的友元类,B
并不会自动成为 A
的友元类。
3.友元关系不能继承。如果 A
是 B
的友元类,A
的派生类不会自动成为 B
的友元类。
3. 友元的注意事项
1.破坏封装性:友元机制破坏了类的封装性,因此应谨慎使用。只有在确实需要访问私有成员时才使用友元。
2.不可传递:友元关系不具有传递性。如果 A
是 B
的友元,B
是 C
的友元,A
并不会自动成为 C
的友元。
3.不可继承:友元关系不会被子类继承。
4. 友元的典型应用场景
4.1 操作符重载
友元函数常用于操作符重载,特别是当操作符需要访问类的私有成员时。例如,重载 <<
操作符以支持自定义输出:
class MyClass {
private:
int data;
public:
MyClass(int d) : data(d) {}
// 声明友元函数
friend std::ostream& operator<<(std::ostream& os, const MyClass& obj);
};
// 定义友元函数
std::ostream& operator<<(std::ostream& os, const MyClass& obj) {
os << "Data: " << obj.data;
return os;
}
int main() {
MyClass obj(42);
std::cout << obj << std::endl; // 输出: Data: 42
return 0;
}
4.2 跨类协作
当两个类需要紧密协作,且需要访问彼此的私有成员时,可以使用友元类。
class A {
private:
int secret;
public:
A(int s) : secret(s) {}
friend class B; // 声明 B 为友元类
};
class B {
public:
void showSecret(const A& a) {
std::cout << "A's secret: " << a.secret << std::endl;
}
};
int main() {
A a(100);
B b;
b.showSecret(a); // 输出: A's secret: 100
return 0;
}
5. 总结
友元函数:允许非成员函数访问类的私有和保护成员。
友元类:允许另一个类的所有成员函数访问当前类的私有和保护成员。
使用场景:操作符重载、跨类协作等。
注意事项:友元机制破坏了封装性,应谨慎使用。