我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++超详细讲解友元与内部类

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++超详细讲解友元与内部类

一.友元

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

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

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

到此这篇关于C++超详细讲解友元与内部类的文章就介绍到这了,更多相关C++友元与内部类内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C++超详细讲解友元与内部类

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java语言中4种内部类的超详细讲解

这篇文章主要给大家介绍了关于Java语言中4种内部类的超详细讲解,内部类可以分为:实例内部类、静态内部类和成员内部类,每种内部类都有它特定的一些特点,文中介绍的非常详细,需要的朋友可以参考下
2023-05-17

TypeScript条件类型与内置条件类型超详细讲解

我们可以使用TypeScript中的条件类型来根据逻辑定义某些类型,就像是在编写代码那样。它采用的语法和我们在JavaScript中熟悉的三元运算符很像:condition?ifConditionTrue:ifConditionFalse。我们来看看他是怎么工作的
2023-03-09

C语言可变参数与内存管理超详细讲解

有时,您可能会碰到这样的情况,您希望函数带有可变数量的参数,而不是预定义数量的参数。C语言为这种情况提供了一个解决方案,这篇文章主要介绍了C语言可变参数与内存管理
2023-01-02

C++嵌套类与局部类详细解析

从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用。如果在外围类之外的作用域使用该类名时,需要加名字限定
2022-11-15

JavaScriptES6中类与模块化管理超详细讲解

JavaScript中的模块化是指将每个js文件会被认为单独一个的模块。模块之间是互相不可见的。如果一个模块需要使用另一个模块,那么需要通过指定语法来引入要使用的模块,而且只能使用引入模块所暴露的内容
2023-01-11

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录