友元
概念
友元可以访问与其有好友关系的类中的成员。
友元提供不同类的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。
实际是对封装的破坏
友元既可以是不属于任何类的一般函数,也可以是另一个类的成员函数,还可以是整个的类。
包括:
-
友元函数
-
不是当前类的成员函数,而是独立于当前类的外部函数
-
可以访问该类的所有对象的成员,包括私有、保护、公有成员
-
声明:
- 位置:类体中
- 格式:函数名前加
friend
-
定义:
-
类体内:函数名前加
friend
-
Example 1. 在类内定义友元函数
-
-
类体外:同一般函数(函数名前不能加
类名::
,因为友元函数不是类的成员函数)-
Example 2. 在类外定义友元函数
-
-
不是类所独有,尽量定义在类体外
-
Example 3. 友元函数在多个类中
#include <iostream> #include <string.h> using namespace std; class boy; class girl { private: char name[25]; int age; public: girl(char N[], int a) { age = a; strcpy(name, N); } friend void prdata(const girl plg, const boy plb); //in class girl }; class boy { private: char name[25]; int age; public: boy(char N[], int a) { age = a; strcpy(name, N); } friend void prdata(const girl plg, const boy plb); //in class boy }; void prdata(const girl plg, const boy plb) //definition { cout << "name:" << plg.name << endl << "age:" << plg.age << endl << "name:" << plb.name << endl << "age:" << plb.age << endl; }; int main() { girl g1("Zhang Hao", 12), g2("Li Ying", 13), g3("Wan Hong", 16); boy b1("Chen Lin", 14), b2("Wang Hua", 13), b3("Bai xun", 16); prdata(g1, b1); prdata(g2, b2); prdata(g3, b3); return 0; } /* name:Zhang Hao age:12 name:Chen Lin age:14 name:Li Ying age:13 name:Wang Hua age:13 name:Wan Hong age:16 name:Bai xun age:16 */
-
-
友元函数没有this指针,通过入口参数(该类对象)来访问对象的成员
-
-
友元成员
-
友元函数可以是一般函数(非成员函数),也可以是另一个类中的成员函数
-
一个类的成员函数也可以作为另一个类的友元,指针成员函数不仅可以访问自己所在类对象中的所有成员,还可以访问
friend
声明语句所在类对象中的所有成员 -
以上两条其实本质是一致的,都是友元成员
- 一个类的成员函数作为另一个类的友元函数时,必须先定义这个类
-
Example 4
#include <iostream> using namespace std; class Date; class Time { public: Time(int h, int m, int s) { hour = h, minute = m, sec = s; } void display(Date &); private: int hour, minute, sec; }; class Date { public: Date(int m, int d, int y) { month = m, day = d, year = y; } friend void Time::display(Date &); //友元函数在Date类中是,是Time类的成员函数 private: int month, day, year; }; void Time::display(Date &d) { cout << d.month << "/" << d.day << "/" << d.year << endl; cout << hour << ":" << minute << ":" << sec << endl; } int main() { Time t1(10, 13, 56); Date d1(12, 25, 2004); t1.display(d1); return 0; } /* 12/25/2004 10:13:56 */
-
-
友元类
-
Example 4. 友元类
class CCar { private: int price; friend class CDriver; //声明 CDriver 为友元类 }; class CDriver { public: CCar myCar; void ModifyCar() //改装汽车 { myCar.price += 1000; //因CDriver是CCar的友元类,故此处可以访问CCar的私有成员 } };
-
如上Example中,CDriver类中所有的成员函数都是CCar类的友元函数
-
友元的关系是单向的,不是双向的
- X类是Y类的友元,类Y不一定是类X的友元
-
友元关系不能传递
- X类是Y类的友元,Y类是Z类的友元,X类不一定是类Z的友元
-
实际应用中,除非确有必要,一般不把整个类声明为友元类,而只将确实有需要的成员函数声明为友元函数,这样更安全
-