【学习笔记】C++之友元

本文详细介绍了C++中的友元函数和友元类的概念及使用。友元函数可以访问类的私有和保护成员,而友元类的所有成员函数都有此权限。友元关系不具传递性,且不能通过对象调用友元函数。示例展示了如何声明和使用友元函数以及友元类。
摘要由CSDN通过智能技术生成

【学习笔记】C++之友元

一、友元函数
//Example1.
/*===============================================================
*   Copyright (C) 2021 All rights reserved.
*   
*   文件名称:friend.cpp
*   创 建 者:RiSK
*   创建日期:2021年08月10日
*   描    述:
*
*   更新日志:
*
================================================================*/
using namespace std;
#include <iostream>
class Demo
{
public:
	Demo(int x,int y);
	void setVal(int x,int y);
	int getVal();
	friend int add(Demo &obj);//声明该函数为友元函数
private:
	int x;
	int y;
	static int z;

};
int Demo::z=15;

Demo::Demo(int x,int y):x(x),y(y)
{
	cout << __func__ << ":" << __LINE__ <<endl;
}

void Demo::setVal(int x,int y)
{
	this->x = x;
	this->y = y;
}

int Demo::getVal()
{
	return x;
}

int add(Demo &obj)//友元函数在类体之外的定义
{
	Demo::z = 17;//z 为静态的成员 与对象无关联
//	z == 17;
	return obj.x + obj.y;
}
//友元函数:
//	1、成员函数声明之前使用 friend 修饰,定义时不需要
//	2、友元函数在类体之外定义时,就像普通函数定义一样,不能有 类名::
//	3、友元函数打破了类的封装和隐藏,就不再是类的成员函数
//	4、友元函数打破了类的封装,意味着在该函数体当中可以通过该类对象去访问 该类的私有成员(在该友元函数体中,没有任何的权限限制)
int main()
{
	Demo obj(3,5);

	obj.setVal(1,3);
	//cout << obj.add() <<endl;//错误,友元函数不是类的成员函数,不能通过对象调用
	//cout << Demo::add() <<endl;
	cout << add(obj) << endl;//友元函数的调用
	return 0;
}
1、成员函数声明之前使用friend修饰,定义时不需要
friend int add(Demo &obj);//声明该函数为友元函数

int add(Demo &obj)//友元函数在类体之外的定义
{
	Demo::z = 17;//z 为静态的成员 与对象无关联
	return obj.x + obj.y;
}
2、友元函数在类体之外定义时,就像普通函数定义一样,不能有 类名::
int add(Demo &obj)//友元函数在类体之外的定义
{
	Demo::z = 17;//z 为静态的成员 与对象无关联
	return obj.x + obj.y;
}
3、友元函数打破了类的封装和隐藏,就不再是类的成员函数
int add(Demo &obj)//友元函数在类体之外的定义
{
	Demo::z = 17;//z 为静态的成员 与对象无关联
    //z = 17;//错误,友元函数不再是类的成员函数
	return obj.x + obj.y;
}

	//cout << obj.add() <<endl;//错误,友元函数不是类的成员函数,不能通过对象调用
	//cout << Demo::add() <<endl;//错误,友元函数不是类的成员函数,亦不能通过作用域访问
4、友元函数打破了类的封装,意味着在该函数体当中可以通过该类对象去访问 该类的私有成员(在该友元函数体中,没有任何的权限限制)
Demo obj(3,5);//定义obj对象并初始化
obj.setVal(1,3);//设置值
cout << add(obj) << endl;//友元函数的调用
二、友元类
//Example2.
/*===============================================================
*   Copyright (C) 2021 All rights reserved.
*   
*   文件名称:friend.cpp
*   创 建 者:RiSK
*   创建日期:2021年08月10日
*   描    述:
*
*   更新日志:
*
================================================================*/
using namespace std;
#include <iostream>

class A
{
public:
	A(int x):x(x){}//构造函数
private:
	int x;
	friend class B;//说明B类是A类的友元类,也就是A将B当朋友,可以声明在任何权限下。
	static int y;//定义静态成员变量
};

int A::y = 13;//初始化A类中y静态成员变量

class B
{
public:
	void showMsg(A &obj)
	{
		cout << A::y <<endl;
		cout << obj.x <<endl;
	}
	friend class C;//说明C类是B类的友元类,也就是B将C当朋友,可以声明在任何权限下
private:
	static int x;
};
int B::x = 15;

class C 
{
public:
	void prnmsg()
	{
		cout << B::x << endl;
		//cout << A::y << endl;//友元关系不具备传递性
		A obj(4);
		B::showMsg(obj);
	}
};

int main()
{
	A obj(5);
	B obj1;

	obj1.showMsg(obj);
}

1、如果B是A的友元类,那么B类中所有成员 都会打破A类的封装
class B
{
public:
	void showMsg(A &obj)
	{
		cout << A::y <<endl;//在B类的成员函数中,可以直接通过 A::成员名 访问A类静态成员
		cout << obj.x <<endl;在B类的成员函数中,可以通过A类对象访问 A类的任何成员
	}
	friend class C;//说明C类是B类的友元类,也就是B将C当朋友,可以声明在任何权限下
private:
	static int x;
};
2、友元关系不能被继承、友元关系是单向的、友元关系不具备传递性
class C 
{
public:
	void prnmsg()
	{
		cout << B::x << endl;
		//cout << A::y << endl;//友元关系不具备传递性
		A obj(4);
		B::showMsg(obj);
	}
};

转载请标明出处

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值