1.友元的背景:C++提供了三大访问控制权限用于控制类外,类内,子类内对成员的访问的控制.
2.友元就是一个类对某个对象授予所有的访问控制权限
- 例如
MyClass
有一个私有的成员变量m_nNum
- 在main函数中是不能直接通过对象来访问的. 但是通过友元授权,main也能直接通过对象来访问到这个类的所有成员.
3.友元能够授予权限的对象:
- 友元普通函数 : 将类的访问权限全部授予一个普通的函数
class MyClass{ int m_nNum; static int m_staticNum; // 使用friend关键字将某个普通函数的函数头放在类内声明 // 这个普通函数就能成为本类友元普通函数. friend int main(); }; int MyClass::m_staticNum; int main(){ MyClass obj; obj.m_nNum=0;// 成为友元之后可以访问私有成员 MyClass::m_staticNum=0; }
- 友元类 : 将本类的访问权限全部授予给另一个类(在另一个类的所有成员函数中都能直接访问到授权类的所有成员)
class MyClass{ int m_nNum; static int m_staticNum; // 声明一个友元类: friend class 类名; // 作用: 该类所有成员函数都能访问本类的 // 私有成员. friend class Class2; }; int MyClass::m_staticNum; class Class2{ public: void fun(MyClass& obj){ // 声明友元类之后, 就能在成员函数中 // 去访问MyClass类的私有变量 obj.m_nNum = 0; } };
- 友元成员函数 : 将本类的访问权限全部授予给另一个类某个成员函数(只有被授权的成员函数能够访问所有成员,没有被授权的成员函数访问不了)
- 互相引用的问题 : 在A类中使用了B类, B类又使用了A类. 类的声明就无法正常声明了.
class MyClass2 { public: void fun1(); void fun2(); }; class MyClass1 { int m_nNum; public: // 声明友元成员函数 friend void MyClass2::fun1(); }; void MyClass2::fun1() { MyClass1 obj; // 访问私有成员变量 obj.m_nNum = 0; } void MyClass2::fun2() { MyClass1 obj; // 访问私有成员变量, 但fun2并没有被声明成友元成员函数. 因此访问失败. obj.m_nNum = 0; }
- 如果是多个文件的处理方式:
Test1.h文件 #pragma once #include "Test2.h" class Test1 { private : int nums; public: Test1(); ~Test1(); friend void Test2::fun(); }; Test2.h文件 #pragma once class Test2 { public: Test2(); ~Test2(); void fun(); }; Test2.cpp文件 #include "Test2.h" #include "Test1.h" Test2::Test2() { } Test2::~Test2() { } void Test2::fun() { Test1 test; test.nums = 10; } //在Test2.h文件中不包含Test1.h的内容防止相互包含 //应该在Test2.cpp文件中进行包含Test1.h的内容 //解决两个类相互包含的问题 Test2.h文件 #pragma once class Test1;//这里前置声明Test1是一个类 class Test2 { private: Test1 *test;//这里使用Test1的指针,因为只声明Test1是一个类,但是并没有具体的定义,所以这里只能使用指针,而在Test.cpp文件中就应该引入完整的Test1类也就是Test1.h文件 public: Test2(); ~Test2(); void fun(); }; Test2.cpp文件 #include "Test2.h" Test2::Test2() { } Test2::~Test2() { } void Test2::fun() { // Test1 test; // test.nums = 10; } Test1.h文件 #pragma once #include "Test2.h"//另一个类直接包含整个Test2.h文件 class Test1 { private : int nums; public: Test1(); ~Test1(); friend void Test2::fun(); };
- 互相引用的问题 : 在A类中使用了B类, B类又使用了A类. 类的声明就无法正常声明了.
- 运算符重载有关-->转至运算符重载