C++ 友元函数和友元类

前言

        在本文中,您将学习在C ++中创建友元函数和友元类,并在程序中有效地使用它们。OOP的重要概念之一是数据隐藏,即非成员函数无法访问对象的私有或受保护的数据。但是,有时这种限制可能迫使程序员编写冗长而复杂的代码。因此,C ++编程内置了一种机制,可以从非成员函数访问私有或受保护的数据,这是使用友元函数和友元类完成的。

C ++中的友元函数

        如果将函数定义为友元函数,则可以使用函数访问类的私有数据和受保护数据。通过使用关键字friend,编译器知道给定的函数是友元函数。要访问数据,应该在类的内部以关键字friend开始声明友元函数(可以是类内部的任何地方,可以是private部分,也可以是public部分)。

C ++中的友元函数声明

class class_name
{
    ... .. ...
    friend return_type function_name(argument/s);
    ... .. ...
}

现在,您可以将友元函数定义为访问该类数据的普通函数。friend定义中未使用任何关键字。

class className
{
    ... .. ...
    friend return_type functionName(argument/s);
    ... .. ...
}

return_type functionName(argument/s)
{
    ... .. ...
    // 可以从这个位置访问className的私有和受保护数据
     //因为此函数是className的友元函数。
    ... .. ...
}

 

/* C ++程序演示友元函数的工作。*/
#include
class base {
public:
	
	// 友元函数
	friend int display_friend(base);
private:
	int a = 1;
protected:
	int b = 2;
};

// 友元函数的定义
int display_friend(base m) {
	//从非成员函数访问私有数据和受保护数据
	int c = m.a + m.b;
	return c;
}

int main() {
	base base1;
	std::cout << "输出:" << display_friend(base1) << std::endl;
	system("pause");
	return 0;
}

输出结果:

3

分析:

        这里,友元函数display_friend() 在base类中声明。因此,可以从这个函数访问类中的私有数据和受保护数据。

若将友元函数在类中的声明去掉,则程序会报错:
去掉友元函数在类中的声明之后代码如下:

/* C ++程序演示友元函数的工作。*/
#include
class base {
public:
	
	// 友元函数
	//friend int display_friend(base);
private:
	int a = 1;
protected:
	int b = 2;
};

// 友元函数的定义
int display_friend(base m) {
	//从非成员函数访问私有数据和受保护数据
	int c = m.a + m.b;
	return c;
}

int main() {
	base base1;
	std::cout << "输出:" << display_friend(base1) << std::endl;
	system("pause");
	return 0;
}

编译器报错: 

C++ 友元函数和友元类_第1张图片

使用友元函数添加两个不同类的私有或受保护成员变量

#include
class base2; // 类base2的前置声明

class base1 {
public:
	
	// 友元函数声明
	friend int display_friend(base1, base2);
private:
	int a = 1;
};

class base2 {
public:
	// 友元函数声明
	friend int display_friend(base1, base2);

protected:
	int b = 2;
};

// 友元函数的定义
// 函数display_friend()是类base1和base2的友元函数
int display_friend(base1 m1, base2 m2) {
	//从非成员函数访问私有数据和受保护数据
	int c = m1.a + m2.b;
	return c;
}

int main() {
	base1 A;
	base2 B;
	std::cout << "输出:" << display_friend(A, B) << std::endl;
	system("pause");
	return 0;
}

 输出结果:

3

分析:

        在这个程序中,类base1和base2已经将display_friend()声明为friend函数。因此,这个函数可以访问这两个类的私有数据或受保护数据。在这里,display_friend()函数将两个对象A和B的私有数据 a 和受保护数据 b 相加,并将其返回给main函数。

        为了使这个程序正常工作,应该像上面的实例中所示的那样,对一个类base2进行前置声明。这是因为使用以下代码在class base1中引用了class base2的友元函数:friend int display_friend(base1,base2);

友元类(friend class)

        类似地,像一个友元函数一样,一个类也可以使用关键字friend成为另一个类的友元类。例如:

... .. ...
class B;
class A
{
   // class B 是 class A的友元类
   friend class B;
   ... .. ...
}

class B
{
   ... .. ...
}

        当一个类成为另一个类的friend类(友元类)时,这就意味着这个类的所有成员函数都是另一个类的友元函数。

        在这个程序中,B类的所有成员函数都是A类的朋友函数,因此B类的任何成员函数都可以访问A类的私有和受保护的数据,但是A类的成员函数不能访问B类的数据。

例如下面的代码:

#include
class B; // 前置声明

class A {
	 // class B 是class A的友元类
	friend class B;

private:
	int a = 1;
protected:
	int b = 2;
};

class B {

public:
	// 类B的成员函数
	int displayB(A a1) {
		int c = a1.a + a1.b;
		return c;
	}
};

int main() {
	A a2;
	B b2;
	std::cout << b2.displayB(a2) << std::endl;
}

输出结果:

3

分析: 

        类B 为类A 的友元类,类B中的成员函数可以访问类A的私有数据和受保护数据。

C ++编程中如何互为友元类

        如何实现classA与B互为友元,即A可以访问B的私有,B也可以访问A的私有呢?案例如下:

#include
class B; // 前置声明

class A {
	 // class B 是class A的友元类
	friend class B;

private:
	int a = 1;
protected:
	int b = 2;
public:
	int displayA(B);
};

class B {
	// class A 是class B 的友元类
	friend class A;

public:
	// 类B的成员函数
	int displayB(A a1) {
		int c = a1.a + a1.b;
		return c;
	}
private:
	int e = 3;
protected:
	int f = 4;
};


// 类A的成员函数
int A::displayA(B b1) {
	int g = b1.e + b1.f;
	return g;
}

int main() {
	A a2;
	B b2;
	std::cout << b2.displayB(a2) << std::endl; // 3
	std::cout << a2.displayA(b2) << std::endl; // 7
}

输出结果:
3
7

互为友元类的做法就是,在class A中声明friend class B;在classB 中声明friend class A;

注意:类A中使用到了类B的地方必须在类B的声明后定义,在类A中只能声明。例如上边类A中的displayA() 函数,不能在类A中直接定义,只能放在类B的声明之后定义。

你可能感兴趣的:(C++,c++,学习,开发语言)