【带头学C++】----- 九、类和对象 ---- 9.12 C++之友元函数(9.12.1---12.4)
??????????????????????创做不易,麻烦点个关注????????????????????????
??????????????????文末有惊喜!献舞一支!????????????????????
目录
9.12 C++之友元函数
问题:什么是友元函数?
????????在 C++ 中,友元函数是指在一个类的外部定义的、被该类声明为友元的非成员函数。友元函数可以访问该类的所有成员(包括私有成员),并且可以在不通过类对象进行访问的情况下改变成员的值。
? ? ? ? 类的拥有不同权限访问函数的一个主要特点,即类的私有成员无法在类的外部(作用域之外)访问。但是,我们上一小节文章末尾留下了一个疑惑,在有时候需要在类的外部访问类的私有成员怎么办?
????????解决方法是使用友元函数,友元函数是一种特权函数,C++允许这个特权函数访问私有成员。这一点从现实生活中也可以很好的理解。比如你的钱是你个人私有的,你家里人拿你的钱你是可以允许的,但是一个陌生人来拿你的钱,你就不能直接给他了。这时候你家人出来一个说这是他的律师来,是他的朋友,拿了一个东西证明了这个关系(friend == 合法合同、或者律师证,或者你的电话,或者你本人,用来证明你们朋友关系的纽带),这样就可以把你个人的钱给他了。我们可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。
? ? ?(👮👮👮这里提醒大家,不要轻易给陌生人转账、发红包、汇款等,任何!所有!一切!让你先转账才可以得到什么的理由!!!都是诈骗!!!并且不是通过购物平台或者官方的平台的,私人的那种,而且交易方式没有实名等!都是骗子!警惕诈骗,转账之前一定要确认对方是否是你认识的人,或者是你的家人等等。警防网络诈骗,让骗子无处可骗。防诈骗从每个人做起👮👮👮)
? ? ? ? 特别的:友元函数会破坏类的封装性😭,因为私有数据可以被外部访问到
9.12.1 友元函数的声明friend
????????友元函数使用friend关键字声明一个函数为友元函数。
? ? ? ? friend关键字只使用于声明处,一个函数或者是类对象作为另外一个类的友元,例如A类作为B类的友元,那么A类可以直接访问B类中的私有数据。
? ? ? ? 友元比较着重运用在运算符重载上。
9.12.2 普通全局函数作为类的友元函数
这里我们使用了一个案例举例:是在千锋教育C++嵌入式基础班讲解(后续案例用qf缩写代替)的一个案例:例如你的家,有客厅,有你的卧室,那么你的客厅是Public的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的好闺蜜、好基友进去参观你的卧室(基于正常情况,防止杠精)。
1.当不是友元的时候,访问私有成员会报错的
当使用相同名字的时候,声明为友元函数的时候,公共函数visitingfun()就没有报错。?
完整案例+结果
代码:
#include <iostream>
#include <string>
using namespace std;
class Room
{
friend void visitingfun(Room &room);
private:
string bedRoom;//卧室public:
public:
string setingRoom;//客厅pubTic:
public:
Room(string bedRoom, string setingRoom){
this->bedRoom = bedRoom;
this->setingRoom = setingRoom;
}
};
//普通全局函数
void visitingfun(Room &room){
cout<<"访问了"<<room.setingRoom<<endl;
cout<<"访问了"<<room.bedRoom<<endl;
}
void test01(){
Room room("私人豪华大床房卧室","公共188大平层客厅");
visitingfun(room);
}
int main()
{
test01();
return 0;
}
9.12.3 类的某个成员函数作为另外一个类的友元函数
这个案例中,goodfriens类中的vistinng_02成员函数作为Room1类的友元函数。此时就是不同类的成员,进行一个私有成员变量的访问。
拓展:
?上面的案例中,成员函数声明和定义顺序比较关键,总所周知,程序是向下编译的,顺序执行。
那看下面这个图片中:成员函数放到类对象里,此时报错原因,即使你提前声明了Room1,但是由于初始化阶段,还没有生成Room1的成员,此时编译器是不知道Room1里面有什么成员的。所以此时报错了。
另外,goodfriends的声明也应该在Room1声明之前(这里仅仅针对9.12.3主题来说,因为你要的是成员函数)?,编译器提前声明只是知道了一个名字,编译顺序始终是从上往下执行的。
所以,你要把类中要成为友元函数的成员函数,定义实现放在外面,放在所有类的声明的后面就行了。
9.12.4 整个类作为另外一个类的友元
????????就是这个类的所有成员函数都可以访问另一个类的私有数据。
并且,声明的顺序可成员函数的基本一致。
?代码:
class Room1;//向前声明方式,这样只能说明类的名称
class goodfrieds
{
public:
void visiting_01(Room1 &room);
void visiting_02(Room1 &room);
};
class Room1{
//friend void goodfrieds::visiting_02(Room1 &room);
friend class goodfrieds;
private:
string bedRoom;//卧室public:
public:
string setingRoom;//客厅pubTic:
public:
Room1(string bedRoom, string setingRoom){
this->bedRoom = bedRoom;
this->setingRoom = setingRoom;
}
};
void goodfrieds::visiting_01(Room1 &room){
cout<<"访问了01"<<room.setingRoom<<endl;
cout<<"访问了01"<<room.bedRoom<<endl;
}
void goodfrieds::visiting_02(Room1 &room){
cout<<"访问了02"<<room.bedRoom<<endl;
cout<<"访问了02"<<room.setingRoom<<endl;
}
void test03(){
Room1 room("私人豪华大床房卧室","公共188大平层客厅");
goodfrieds ob;
ob.visiting_01(room);
ob.visiting_02(room);
}
int main()
{
test03();
return 0;
}
点赞👍? + 收藏👐 + 关注👌
??您的支持??是我最大的动力??相互学习??共同进步??一起搞钱??动动发财的小手??
? ????????????????????十星好评,Erike的专用模板????????????????????
谢? ? ?谢? ? ?老? ? ?板!老? ? ?板? ? ?大? ? ?气!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!