C++ 友元

974 阅读3分钟

引入友元的目的

采用了类的机制后实现了数据的封装与隐藏,只有类的成员函数才能访问类的私有成员,外部函数只能访问类的公有成员,不能访问类的私有成员。 采用友元可以解决这一问题。 友元(friend, 即是“朋友”意思)可以在类外直接访问类的私有成员,提高了程序的运行效率。

友元提供了在不同类的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。 通过友元,一个普通函数或另一个类中的成员函数可以访问类中的私有成员。C++中的友元为封装隐藏这堵不透明的墙开了一个小孔,外界可以通过这个小孔窥视内部的“秘密”。 友元的使用能提高程序的运行效率, 但破坏了类的封装性和数据的隐蔽性,因此一定要谨慎使用。

友元的种类: 1)、友元函数:包括普通函数作为友元、其它类的成员函数作为友元 2)、友元类

友元函数

声明:

格式1:
class 类名
	{
	…
	friend 类型 函数名(形参表);
…
};
…
//函数的类外定义
类型 函数名(形参表)
{
	…
}
格式2:
class 类名
	{
	…
	//函数的类内定义
	friend 类型 函数名(形参表)
{
		… 
	}
…
};

说明:格式1、格式2 只是友元函数定义的位置不同,两者效果完全一样。

class A{
	//友元函数
	friend void modify_i(A *p, int a);
private:
	int i;
public:
	A(int i){
		this->i = i;
	}
	void myprint(){
		cout << i << endl;
	}
};


//友元函数的实现,在友元函数中可以访问私有的属性
void modify_i(A *p, int a){
	p->i = a;
}

void main(){
	A* a = new A(10);
	a->myprint();

	modify_i(a,20);
	a->myprint();

	system("pause");
}

C++.png

说明: 1)友元函数的声明可放在类的公有、私有或保护部分,结果是一样的(下同,不再一一说明)。 2)友元函数虽是在类中说明的一个函数,它不是该类的成员函数,所以,函数定义时不需要在函数名前加类名::; 3)友元函数不是类的成员,所以没有this指针,访问该类的对象的成员时,必须使用对象名.成员名 格式。通常是用对象作为友元函数的参数; 4)友元函数的作用域从声明点开始,结束点与类相同。因此,友元函数的声明可以代替该函数的说明。

友元类

(1) 特点:该类的所有成员函数都是某一个类的友元函数。  (2)声明格式:(类B是被访问类,类A中的所有成员函数都是B的友元)

class B; 	   //类B的提前引用声明
class A  	   //类A的定义   
	{… };
…
class B  	   //类B的定义 
	{…
	friend class A;
 } ;
	 //类A的多个成员函数类外定义
	 类型 A::成员函数名(形参表){ … }
 …

//友元类
class A{
	//友元类
	friend class B;
private:
	int i;
public:
	A(int i){
		this->i = i;
	}
	void myprint(){
		cout << i << endl;
	}
};

class B{
public:
	//B这个友元类可以访问A类的任何成员
	void accessAny(){
		a.i = 30;
	}
private:
	A a;
};

说明:

1)友元类的所有成员函数都是友元函数,都具有访问被访问类所有成员的权限; 2)这里也涉及到两个类:一个是被访问的类,另一个是提供友元函数的访问类,也存在被访问类要提前声明的问题; 3)请按如下次序进行声明或定义,这样不会出错:被访问类的提前声明->定义友元类->定义被访问的类(包含友元类的声明)->友元类的所有成员函数类外定义。

调用:对象名.成员函数(实参表)