[C++ 从入门到精通] 15.友元函数、友元类、友元成员函数
2023-12-18 09:52:56
- 📢博客主页:https://loewen.blog.csdn.net
- 📢欢迎点赞 👍 收藏 ?留言 📝 如有错误敬请指正!
- 📢本文由 丶布布原创,首发于 CSDN,转载注明出处🙉
- 📢现在的付出,都会是一种沉淀,只为让你成为更好的人?
一. 前言
众所周知,C++
控制对类对象私有成员的访问。通常,公有类方法(public
)提供唯一的访问途径,但是有时候这种限制太严格,以至于不适合特定的编程问题。
在这种情况下,C++
提供了另外一种形式的访问权限:友元,友元有3
种:
- 友元函数;
- 友元类;
- 友元成员函数;
优缺点
-
优点:通过让函数成为类的友元(即:友元函数),可以赋予该函数与类的成员函数相同的访问权限,使其可以访问本类
protected、private
成员,在某些频繁访问成员变量的地方可以提高性能。 -
缺点:友元破坏了面向对象的封装性。
二. 友元函数
1、通过friend
将一个函数(友元函数是个函数)声明为某个类的友元函数,那么该函数就能访问这个类的所有成员(成员变量、成员函数),无论是public,private,protected
。
2、因为友元函数不属于类成员,所以其不受public/protected/private
的限制,放在public/protected/private
下声明都行。
代码展示:
#include <iostream>
using namespace std;
class A
{
private:
int data;
void display(){
cout << "data = " << data << endl;
}
friend void change(int x, A& a); // 将函数change()声明为类A的友元函数
};
void change(int x, A& a)
{
a.data = x;
a.display();
}
int main()
{
A a;
change(10, a);
return 0;
}
三. 友元类
1、可以在类A
中把类B
声明为类A
的友元类,此时,在类B
(类A
的友元类)的成员函数中,可以访问类A
的所有成员(成员变量、成员函数),无论是public,private,protected
。
2、由于友元类不属于类成员,所以友元类的声明不受public、protected、private
的影响。
代码展示(Tip
:为什么需要类B
的声明):
#include <iostream>
using namespace std;
class B; // 类B的声明,类A用到了类B,而类B的定义有可能在类A的定义之后导致编译出错,所以最好先声明一下类B
class A
{
private:
int data;
void display()
{
cout << "data = " << data << endl;
}
friend class B; // 将类B声明为类A的友元类(用到了类B的名字,所以需要前面声明一下class B; )
};
class B
{
public:
void change(int x, A& a)
{
a.data = x; //在类B(类A的友元类)的成员函数中,可以访问类A的所有成员(成员变量、成员函数),无论是public,private,protected
a.display();
}
};
int main()
{
A a;
B b;
b.change(50, a);
return 0;
}
注意:每个类都负责控制自己的友元类和友元函数:
- 友元关系不能被继承;
- 友元关系是单向的,比如类
B
是类A
的友元类,但这并不代表类A
是类B
的友元类; - 友元关系没有传递性,比如类
B
是类A
的友元类,类C
是类B
的友元类,但这并不代表类C
是类A
的友元类;
四. 友元成员函数
友元成员函数:即是本类的成员函数,又是其他类的友元函数。
代码展示:
A.h(Tip
:为什么使用#include "B.h"
而不用class B;
声明类B
)
#ifndef __A_H
#define __A_H
#include <iostream>
//class B; //注:声明友元成员函数不能仅仅使用类B的声明了,因为在friend void B::change(int x, A& a)不仅仅用到了类B的名字,
//还用到了其成员函数change(),系统需要先判断类B中是否有其成员函数change(),所以需要用#include "B.h"
#include "B.h"
class A
{
private:
int data;
void display()
{
std::cout << "data = " << data << std::endl;
}
friend void B::change(int x, A& a); // 该函数是友元成员函数的声明:将类B的成员函数change()声明为类A的友元函数
};
#endif
B.h
#ifndef __B_H
#define __B_H
class A; // 类A的声明
class B
{
public:
void change(int x, A& a); // 只有public的成员函数才能成为其它类的友元函数
};
#endif
B.cpp
#include "A.h"
#include "B.h"
void B::change(int x, A& a)
{
a.data = x;
a.display();
}
main.cpp
#include "A.h"
#include "B.h"
int main()
{
A a;
B b;
b.change(50, a);
return 0;
}
下雨天,最惬意的事莫过于躺在床上静静听雨,雨中入眠,连梦里也长出青苔。 |
文章来源:https://blog.csdn.net/weixin_43197380/article/details/135054069
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!