【从 C 向 C++ 进阶】- 类 - 10. 友元

从 C 向 C++ 进阶系列导航


1. 友元简介

友元是 C++ 中的一种关系,友元关系发生在函数与类之间或者类与类之间。友元能够了忽略类的封装属性,即不受访问属性的限制,直接访问类的成员变量或成员函数。

友元具备以下特征:

  • 在类中以 friend 关键字声明友元。
  • 友元可以是其它类或具体函数。
  • 友元不受类中访问级别的限制,可以直接访问具体类的所有成员。
  • 友元不是类的一部分,仅是一种关系的声明。
  • 友元关系不能被继承,是单向的,不具交换性,不具传递性。

与类有友元关系的函数称为友元函数,与类有友元关系的类称为友元类。


2. 友元类

友元类可以访问友元类声明所在的类的所有成员函数与变量。声明形式为:friend class Classname

  • 实验:
class Test
{
private:
    int mNum;

public:
    Test(int num)
	{
		this->mNum = num;
	}
	void SetNum(int num)
	{
		this->mNum = num;
	}
	friend class TestFriend;
};

class TestFriend
{
public:
	void PriTestNum(const Test& obj)
	{
		cout << "obj.mNum = " << obj.mNum << endl;    // obj.mNum = 10
		obj.SetNum(5);
		cout << "obj.mNum = " << obj.mNum << endl;    // obj.mNum = 5
		obj.mNum = 10;
		cout << "obj.mNum = " << obj.mNum << endl;    // obj.mNum = 10
	}
};

int main()
{
	Test src_obj(10);
    TestFriend fri_obj;
	fri_obj.PriTestNum(src_obj);    
}

3. 友元函数

友元函数可以访问函数声明所在的类的所有成员函数与变量。一个函数可以是多个类的友元函数,只需要在各个类中分别声明。声明形式为:friend Type Funname(...)

友元函数遵循以下规则:

  • 当友元函数为普通函数时,函数的定义需发生在类的定义之后,或者函数的声明发生在类的声明之后。
  • 当友元函数为其他类成员函数时,必须满足以下两点:
    • 友元函数的所属类需定义在声明所在的类之前。
    • 友元函数的形参所涉及的类需在函数所属类定义之前声明或定义。
  • 两个类之间无法实现互相的友元函数。
  • 实验:
class Test_B;	// 必须进行声明
class Test_A;	// 必须进行声明

int DifClassAdd(Test_A& obj_A, Test_B& obj_B);

class Test_B
{
private:
    int mNum ;
	
public:
	Test_B(int num)
	{
		this->mNum = num;
	}
	void SetNum(Test_A& obj_A, int num);
	// friend void Test_A::PriNum(Test_B &obj_B);	        // invalid use of incomplete type ‘class Test_A’
	friend int DifClassAdd(Test_A& obj_A, Test_B& obj_B);
};

class Test_A
{
private:
    int mNum ;

public:
    Test_A(int num)
	{
		this->mNum = num;
	}
	// void PriNum(Test_B& obj_B);
	friend void Test_B::SetNum(Test_A& obj, int num);
	friend int DifClassAdd(Test_A& obj_A, Test_B& obj_B);
};

void Test_B::SetNum(Test_A& obj_A, int num)
{
	obj_A.mNum = num;
}

// void Test_A::PriNum(Test_B& obj_B)
// {
	// cout << "obj_B.mNum = " << obj_B.mNum << endl;
// }

int DifClassAdd(Test_A& obj_A, Test_B& obj_B)
{ 
	return obj_A.mNum + obj_B.mNum ;
}

int main()
{
	Test_A obj_A(7);
    Test_B obj_B(3);
	obj_B.SetNum(obj_A, 2);
	int sum = DifClassAdd(obj_A, obj_B);
	cout << "obj_A.mNum + obj_B.mNum = " << sum << endl;	// obj_A.mNum + obj_B.mNum = 5
}
发布了60 篇原创文章 · 获赞 36 · 访问量 5954

猜你喜欢

转载自blog.csdn.net/qq_35692077/article/details/96699320