目录
  • 一.友元
    • 1.友元函数
      • (1)引入原因
      • (2)友元函数作用
      • (3)友元函数特征
    • 2.友元类
      • (1)解释
      • (2)友元类特征
  • 二.内部类(不常用)
    • 1.概念
      • 2.特性 

      一.友元

      友元分为: 友元函数 和 友元类

      友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

      1.友元函数

      (1)引入原因

      operator<<:因为cout 的 输出流对象和隐含的 this 指针在抢占第一个参数的位置 。 this 指针默认是第一个参数也就是左操数了。但是实际使用中cout 需要是第一个形参对象,才能正常使用。所以我们要将 operator<< 重载成全局函数。但是这样的话,又会导致类外没办法访问成员,那么这里就需要友元来解决。operator>> 同理。

      (2)友元函数作用

      友元函数 可以 直接访问 类的 私有 成员,它是 定义在类外部 的 普通函数 ,不属于任何类,但需要在类的内部声明,声明时需要加friend 关键字。

      #include<iostream>
      using namespace std;
      class Date
      {
      	// 友元函数
      	friend ostream& operator<<(ostream& out, const Date& d);
      public:
      private:
      	int _year;
      	int _month;
      	int _day;
      };
      ostream& operator<<(ostream& out, const Date& d)
      {
      	out << d._year << "/" << d._month << "/" << d._day << endl;
      	return out;
      }
      int main()
      {
      	Date d;
      	//d << cout;
      	cout << d;
      	return 0;
      }

      (3)友元函数特征

      【1】友元函数 可访问类的私有和保护成员,但 不是类的成员函数

      【2】友元函数 不能用 const 修饰(因为没有this指针)

      【3】友元函数 可以在类定义的任何地方声明, 不受类访问限定符限制,放在public,private中都行,不放这两个里面放在最前面也行,一般都是定义最前面的

      【4】一个函数可以是多个类的友元函数

      【5】友元函数的调用与普通函数的调用和原理相同

      2.友元类

      (1)解释

      class Date; // 前置声明:因为编译器是向上查找,在Time类中
      class Time
      {
          //友元类
      	friend class Date; 
      声明日期类为时间类的友元类,则在日期类中就可以直接访问Time类中的私有成员变量
      public:
      	Time(int hour=0, int minute=0, int second = 0)
      		: _hour(hour)
      		, _minute(minute)
      		, _second(second)
      	{}
      private:
      	int _hour;
      	int _minute;
      	int _second;
      };
      class Date
      {
      public:
      	Date(int year = 1900, int month = 1, int day = 1)
      		: _year(year)
      		, _month(month)
      		, _day(day)
      	{}
      	void SetTimeOfDate(int hour, int minute, int second)
      	{
      		// 直接访问时间类私有的成员变量
      		_t._hour = hour;
      		_t._minute = minute;
      		_t._second = second;
      	}
      private:
      	int _year;
      	int _month;
      	int _day;
      	Time _t;
      };

      在Date类中有一自定义成员变量Time _t;,成员函数 SetTimeOfDate 想访问 _t 对象的成员变量,因为类Time中的成员变量是私有的,所以正常情况无法访问,则需要借助友元类:

      想在Date类中访问Time类对象的私有成员变量,就需要在类Time中声明日期类为时间类的友元类,则在日期类中就可以直接访问Time类中的私有成员变量。

      格式:friend class Date;

      (在Date类中访问Time类对象的成员变量:在Time类中写日期类声明并在前面加friend)

      (2)友元类特征

      【1】友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

      【2】友元关系是单向的,不具有交换性。 比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。

      【3】友元关系不能传递 如果B是A的友元,C是B的友元,则不能说明C时A的友元。

      二.内部类(不常用)

      1.概念

      如果一个类定义在另一个类的内部,这个内部类就叫做内部类。

      注意:此时这个内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去调用内部类。外部类对内部类没有任何优越的访问权限。

      注意:内部类就是外部类的友元类。注意友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。

      2.特性 

      1. 内部类可以定义在外部类的 public 、 protected 、 private 都是可以的。

      2. 注意内部类可以直接访问外部类中的 static 、枚举成员,不需要外部类的对象 / 类名。

      3. sizeof( 外部类 )= 外部类,和内部类没有任何关系

      举例:B是A的内部类,B是A的友元,A不是B的友元,A的大小是4字节,类A的大小不包含静态变量k(存在静态区)和成员函数(存在公共代码段)和内部类B,类A的大小仅仅只有h,所以是4字节。

      class A {
      private:
      	static int k;
      	int h;
      public:
      	class B    //内部类
      	{
      	public:
      		void foo(const A& a)
      		{
      			cout << k << endl;    //B可以直接访问A内部成员变量
      			cout << a.h << endl;    //B可以直接访问A内部成员变量
      		}
      	};
      };
      int main()
      {
      	cout << sizeof(A) << endl;
          A aa;
          A::B bb;    //定义B的对象时,需要指定是A的类域 A::
      	return 0;
      }
      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。