友元
C++中的友元为数据隐藏这堵不透明的墙 开了一个小孔,外界可通过这个小孔窥 视类内部的秘密,友元是一扇通向私有 成员的后门
友元可分为:友元函数 友元成员 友元类
友元函数不是当前类的成员函数,而是独立于当前类的外部函数,但它可以访 问该类的所有对象的成员,包括私有成 员和公有成员
在类定义中声明友元函数时,需在其函 数名前加上关键字friend。此声明可以 放在公有部分,也可以放在私有部分。 友元函数可以定义在类的内部,也可以 定义在类的外部
友元的利弊
友元不是类成员,但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。不过,类的访问权限确实在某些应用场合显得有些呆板,从而容忍了友元这一特别语法现象。
友元函数
class Girl {
char *name;
int age;
public:
Girl(char *name, int age):age(age) {
this->name = new char[strlen(name) + 1];
strcpy(this->name, name);
}
friend void disp(Girl &); //声明为友元函数
};
void disp(Girl &x) {
cout<<x.name<<endl;
cout<<x.age<<endl;
}
Girl girl("zhangsan", 10);
disp(girl);
友元成员
// 使用友元成员函数访问另一个类
#include <iostream>
#include <cstring>
using std::cin;
using std::cout;
using std::endl;
class Girl; //向前引用
//class Boy;
class Boy{
private:
char *name;
int age;
public:
Boy(char *N,int A){
name = new char[strlen(N)+1];
strcpy(name,N);
age = A;
}
void disp(Girl &); //声明disp()为类boy的成员函数
~Boy(){
delete name;
}
};
class Girl{
private:
char *name;
int age;
public:
Girl(char *N,int A){
name = new char[strlen(N)+1];
strcpy(name,N);
age = A;
}
friend void Boy::disp(Girl &); //声明类boy的成员函数disp()为类girl的友元函数
~Girl(){
delete name;
}
};
void Boy::disp(Girl &x)
{
cout<<"boy\'s name is:"<<name<<",age:"<<age<<endl; //访问本类对象成员
cout<<"girl\'s name is:"<<x.name<<",age:"<<x.age<<endl; //访问友元类对象成员
}
int main()
{
Boy b("chen hao",25);
Girl g("zhang wei",18);
b.disp(g);
return 0;
}
友元类
//boy为girl的友元类
#include <iostream>
#include <cstring>
using std::cin;
using std::cout;
using std::endl;
class Girl;
class Boy{
private:
char *name;
int age;
public:
Boy(char *n,int d){
name = new char[strlen(n)+1];
strcpy(name,n);
age = d;
}
void disp(Girl &); //声明disp()为类boy的成员函数
void test(Girl &g);
~Boy(){
delete name;
}
};
class Girl{
private:
char *name;
int age;
friend class Boy; //声明类boy是类girl的友元
public:
Girl(char *n,int d){
name = new char[strlen(n)+1];
strcpy(name,n);
age = d;
}
~Girl(){
delete name;
}
};
void Boy::disp(Girl &x) //定义函数disp()为类boy的成员函数,也是类girl的友元函数
{
cout<<"boy\'s name is:"<<this->name<<",age:"<<age<<endl;
cout<<"girl\'s name is:"<<x.name<<",age:"<<x.age<<endl;
}
void Boy::test(Girl & g)
{
cout<<"in boy test "<<g.name<<endl;
}
int main()
{
Boy b("chen hao",25);
Girl g("zhang wei",18);
b.disp(g);
b.test(g);
return 0;
}
注意事项
(1)友元关系不能被继承。
(2)友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3)友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App