C _复习10(友元函数与友元类)

一、友元函数

1.1 友元函数的定义

类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。

1.2 友元函数的特点

  • 友元函数破坏了类的私有性
  • 友元函数是一个全局函数
  • 友元函数形式:一般情况下都包含类的指针或引用
  • 友元函数在public之下或者是private下都无所谓

1.3 友元函数使用例子

友元函数的调用与一般函数的调用方式和原理一致。

#include <iostream>
using namespace std;
class  A
{
public:
	//声明的位置和public private没有关系
    //友元函数的声明
	friend void modifyA(A *pA,int _a);//函数modifyA是类的好朋友
	A(int a,int b) {
		this->a = a;
		this->b = b;
	 }
	~A() {
		cout << "~A()" << endl;
	}

	void getA() {
		cout << "a: " << this->a << endl;
	}

private:
	int a,b;
};

void modifyA(A *pA,int _a) {
    //通过友元函数访问A的私有属性
	pA->a = _a;
}

int main()
{
	A a1(1,2);
	a1.getA();
	modifyA(&a1, 100);
	a1.getA();
	system("pause");
	return 0;
}

二、友元类

2.1 友元类的定义

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。友元类的应用场景比较死板,通常都是:B是A的好朋友,在B里面组合了一个A的对象,通过B可以直接修改A。A其实就只是一个辅助的类,用来传递消息。

2.2 友元类的特点

  • 若B类是A类的友元类,则B类的所有成员函数都是A泪的友元函数
  • 友元类通常涉及为一种对数据操作或类之间传递消息的辅助类

2.3 友元类例子

#include <iostream>
using namespace std;
class  A
{
public:
	//声明的位置和public private没有关系
	//B是A的友元类
	friend class B;//在B类中可以访问A类的私有成员,或者是私有函数
	friend void modifyA(A *pA,int _a);//函数modifyA是类的友元函数
	A(int a=0,int b=0) {
		this->a = a;
		this->b = b;
	 }
	~A() {
		cout << "~A()" << endl;
	}

	void getA() {
		cout << "a: " << this->a << endl;
	}

private:
	int a,b;
};

void modifyA(A *pA,int _a) {
	pA->a = _a;
}

class B
{
public:
	void set(int a) {
		object.a = 100;
	}
	void printB() {
		cout << object.a << endl;
	}

private:
	A object; //B中有A,A是B的子类
};

void objectPlay01() {
	A a1(1, 2);
	a1.getA();
	modifyA(&a1, 100);
	a1.getA();
}

void objectPlay02() {
	B b1;
	b1.set(300);
	b1.printB();
}

int main()
{
	//objectPlay01();
	objectPlay02();
	system("pause");
	return 0;
}

 2.4 友元类的注意事项

  • 友元关系不能被继承。 
  • 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
  • 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应

2.5 为什么要设计友元类

一般我们所写的.cpp文件会转成为汇编语言,假设没有友元类的情况下。当我们要访问类的私有成员变量的时候,就需要从汇编倒推回去。然而有的时候我却是需要访问私有变量,不能做每时每刻通过汇编这样去找,所以我们做了一个友元函数友元类。等于开了个后门、不然我们就要通过汇编倒推回去

拓展:Java中时通过字节码去找到类对象的。

三、参考链接

https://blog.csdn.net/fanyun_01/article/details/79122916
发布了27 篇原创文章 · 获赞 3 · 访问量 3335

猜你喜欢

转载自blog.csdn.net/weixin_40977054/article/details/102913905
今日推荐