在不放弃私有成员(或保护成员)数据安全性的情况下,使得一个普通函数或者类的成员函数可以访问到封装在某一类中的信息(私有、保护成员)。
C++中的友元为数据隐藏这堵不透明的墙开了一个小孔,外界可以通过这个小孔窥视类内部的秘密,友元是一扇通向私有(保护)成员的后门。如果一个类声明了许多友元,则相当于在墙上开了好多小孔,显然这将破坏数据的隐蔽性和类的封装性,降低了程序的可维护性,因此使用友元函数应谨慎。
C++引入友元机制的目的:
①友元机制是对类的封装机制的补充,利用友元机制,一个类可以赋予某些函数访问它的私有成员的特权。如果没有友元机制,外部函数访问类的私有数据,必须通过调用公有的成员函数,这在需要频繁调用私有数据的情况下,会带来较大的开销,从而降低程序的运行效率。
②友元提供了不同类的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。尤其当一个函数需要访问多个类时,友元函数非常有用,普通的成员函数只能访问其所属的类,但是多个类的友元函数能够访问相关的所有类的数据。
友元包括 友元函数 和 友元类
一、友元函数
- 既可以是不属于任何类的非成员函数,也可以是另一个类的成员函数,统称为友元函数。
- 友元函数不是当前类的成员函数,而是独立于当前类的外部函数,但它可以访问该类所有的成员,包括私有成员、保护成员和公有成员。
- 在类中声明友元函数时,需在其函数名前加上关键字 friend。此声明可以放在公有部分,也可以放在保护部分和私有部分。
- 友元函数可以定义在类内部,也可以定义在类外部。
1、将非成员函数声明为友元函数。
例 1:友元函数的使用。
#include<iostream>
#include<string.h>
using namespace std;
class Girl{
public:
Girl(char *n,int d){
//定义构造函数,为 *name 和 age赋初值
name=new char[strlen(n)+1];
strcpy(name,n);
age=d;
}
friend void disp(Girl &); //声明disp函数为类Girl的友元函数
void show();
~Girl(){
delete name;
}
private:
char *name;
int age;
};
void disp(Girl &x){
cout<<"女孩的姓名是:"<<x.name<<";年龄:"<<x.age<<endl;
}
void Girl::show(){
cout<<"the girl's name is:"<<name<<";age is:"<<age<<endl;
}
int main(){
Girl g1("小红",18);
disp(g1);
g1.show();
return 0;
}
说明:
(1)友元函数虽然可以访问类对象的私有成员,但它毕竟不是成员函数,因此在类的外部定义友元函数时,不必像成员函数那样,在函数名前加上“类名::”。
(2)因为友元函数不是类的成员,所以它不能直接访问对象的数据成员,也不能通过this指针访问对象的数据成员,它必须通过作为入口参数传递进来的对象名(或对象指针,对象引用)来访问引用该对象的数据成员。
(3)由于函数disp是