关于友元的使用

1.友元的背景:C++提供了三大访问控制权限用于控制类外,类内,子类内对成员的访问的控制.

2.友元就是一个类对某个对象授予所有的访问控制权限

  1. 例如MyClass有一个私有的成员变量m_nNum
  2. 在main函数中是不能直接通过对象来访问的. 但是通过友元授权,main也能直接通过对象来访问到这个类的所有成员.

3.友元能够授予权限的对象:

  1. 友元普通函数 : 将类的访问权限全部授予一个普通的函数
    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;
    }

     

  2. 友元类 : 将本类的访问权限全部授予给另一个类(在另一个类的所有成员函数中都能直接访问到授权类的所有成员)

     

    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;
        }
    };

     

  3. 友元成员函数 : 将本类的访问权限全部授予给另一个类某个成员函数(只有被授权的成员函数能够访问所有成员,没有被授权的成员函数访问不了)
    1. 互相引用的问题 : 在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;
      }


       

    2. 如果是多个文件的处理方式:

       

      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();
          };
      

       

  4. 运算符重载有关-->转至运算符重载
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值