【C++】类与对象——友元,内部类,匿名对象

在这里插入图片描述

类与对象

  • 1 友元
    • 1.1 概念:
    • 1.2 友元函数
    • 1.3 友元类
  • 2 内部类
    • 概念:
    • 特性:
    • 举例:
  • 3 匿名对象
  • Thanks♪(・ω・)ノ谢谢阅读!!!
  • 下一篇文章见!!!

1 友元

1.1 概念:

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不易多用
友元分为:友元函数 和 友元类
友元关键字 :friend 可以理解为我把他看做朋友,所以他可以使用我的东西。这就是友元做到的事情是类似的,通过设置友元,在一个类中可以访问类外的函数与变量。

1.2 友元函数

我们现在来实现日期类Date的流输出<<重载,那么我们来看:

class Date
{
public:
   Date(int year, int month, int day)
   {
   	_year = year;
   	_month = month;
   	_day = day;
   	
   }
   //这里 参数有两个 (Date* this , ostream& out )
   //左右操作数不一致。
   ostream& operator<<(ostream& out) {
   	out << _year << '-' << _month << '-' << _day << endl;
   	return out;
   }
private:
   int _year;
   int _month;
   int _day;
};

int main(){
   Date a1(2024,2,24);
   cout << a1;
   return 0;
}

这样必然会出现问题,因为在成员函数中第一个参数默认为(Date* this)所以在使用<<时就会出现参数不匹配环节。
在这里插入图片描述

所以要想改变默认参数的顺序,就要把operator<<重载为全局函数,但是这样无法访问Date的私有变量,此时就可以通过友元来解决这个问题。来看修改后的代码

class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;

	}
	friend ostream& operator<<(ostream& out, Date& d);
private:
	int _year;
	int _month;
	int _day;
};

ostream& operator<<(ostream& out, Date&  d) {
	out << d._year << '-' << d._month << '-' << d._day << endl;
	return out;
}

int main() {
	Date a1(2024, 2, 24);
	cout << a1;
	return 0;
}

现在就可以顺利的使用<<重载了。在这里插入图片描述

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

友元声明只能出现在类定义的内部,但是类内出现的具体位置不限。友元不是类的成员也不受它所在区域访问控制级别的约束。一般来说,最好在类定义开始或结束区域集中声明友元。

注意:

  1. 友元函数可访问类的私有和保护成员,但不是类的成员函数
  2. 友元函数不能用const修饰
  3. 友元函数可以在类定义的任何地方声明,不受类访问限定符限制
  4. 一个函数可以是多个类的友元函数
  5. 友元函数的调用与普通函数的调用原理相同

1.3 友元类

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

  1. 友元关系是单向的,不具有交换性(注意A类中声明友元B类,那么B类可以访问A类,但是A类不能访问B类),类似小明说小刚是他的朋友,但是小刚不一定把小明当做朋友。
  2. 友元关系不能传递(如果C类是B类的友元,B类是A类的友元,不能说明C类是A类的友元)
  3. 友元关系不能继承。

下面给出时间类Time 与 日期类Date 的示例,来帮助我们更好理解友元。
在这里插入图片描述
Time类中声明友元即可成功:

class Time
{
	// 声明日期类为时间类的友元类,
	//则在日期类中就直接访问Time类中的私有成员变量
	friend class Date;
public:
	Time(int hour = 0, int minute = 0, int second = 0)
		: _hour(hour)
		, _minute(minute)
		, _second(second)
	{}
private:
	int _hour;
	int _minute;
	int _second;
};

2 内部类

概念:

如果一个类定义在另一个类的内部,这个内部类就叫做内部类
内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员外部类对内部类没有任何优越的访问权限

特性:

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

  1. 内部类可以定义在外部类的public、protected、private都是可以的。
  2. 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名
  3. sizeof(外部类)=外部类,和内部类没有任何关系

举例:

可以把友元实现的打印日期形成内部类,也可以做到相同效果。

#include<cstdio>
#include<iostream>
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;
	}
	定义内部类
	class Time
	{
		friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类
	中的私有成员变量
	public:
		Time(int hour = 0, int minute = 0, int second = 0)
			: _hour(hour)
			, _minute(minute)
			, _second(second)
		{}
		void show(Date& d){
			printf("时间是 %d年%d月%d日%d时%d分%d秒", d._year, d._month, d._day, 					
			_hour,_minute,_second);
		}
	private:
		int _hour;
		int _minute;
		int _second;
};
private:
	int _year;
	int _month;
	int _day;
	Time _t;
};
int main() {
	Date d1(2024, 2, 26);
	Date::Time t1(11, 26, 30);
	t1.show(d1);
}

来看效果:非常好!!!
在这里插入图片描述

3 匿名对象

匿名对象可以帮助我们优化语句:

class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A(int a)" << endl;
	}
    ~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};
class Solution {
public:
	int Sum_Solution(int n) {
		//...
		return n;
	}
};
int main()
{
	A aa1;
	// 不能这么定义对象,因为编译器无法识别下面是一个函数声明,还是对象定义
	//A aa1();
	// 但是我们可以这么定义匿名对象,匿名对象的特点不用取名字,
	// 但是他的生命周期只有这一行,我们可以看到下一行他就会自动调用析构函数
	A();
	A aa2(2);
	// 匿名对象在这样场景下就很好用,当然还有一些其他使用场景,这个我们以后遇到了再说
	Solution().Sum_Solution(10);
	return 0;
}

Thanks♪(・ω・)ノ谢谢阅读!!!

下一篇文章见!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/410778.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

定制红酒:设计专属标签与包装,打造与众不同个性

在云仓酒庄洒派的定制红酒服务中&#xff0c;为消费者提供个性化、专属的标签与包装设计是提升红酒与众不同性和纪念价值的关键环节。通过巧妙的设计&#xff0c;消费者可以打造出与众不同的红酒&#xff0c;展现自己的个性与品味。 首先&#xff0c;标签设计是展现红酒个性的重…

Mysql 的高可用详解

Mysql 高可用 复制 复制是解决系统高可用的常见手段。其思路就是&#xff1a;不要把鸡蛋都放在一个篮子里。 复制解决的基本问题是让一台服务器的数据与其他服务器保持同步。一台主库的数据可以同步到多台备库上&#xff0c;备库本身也可以被配置成另外一台服务器的主库。主…

MYSQL--(1.存储引擎 *2.事务*)

一 存储引擎: 1.介绍 1>在数据库管理系统当中通过使用数据引擎来实现数据的增删改,查询 2>不同的存储引擎提供的有不同的存储机制,索引技巧等功能 MYSQL的核心,就是存储引擎 3>同样的,用户也可以根据自己的需要进行选择,更改自己需要…

用c# 自己封装的Modbus工具类库源码

前言 Modbus通讯协议在工控行业的应用是很多的&#xff0c;并且也是上位机开发的基本技能之一。相关的类库也很多也很好用。以前只负责用&#xff0c;对其并没有深入学习和了解。前段时间有点空就在这块挖了挖。想做到知其然还要知其所以然。所以就有了自己封装的Modbus工具类库…

Vue+SpringBoot打造在线课程教学系统

目录 一、摘要1.1 系统介绍1.2 项目录屏 二、研究内容2.1 课程类型管理模块2.2 课程管理模块2.3 课时管理模块2.4 课程交互模块2.5 系统基础模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示4.1 管理后台4.2 用户网页 五、样例代码5.1 新增课程类型5.2 网站登录5.3 课…

WampServer环境下载安装并结合内网穿透实现远程访问管理界面

文章目录 前言1.WampServer下载安装2.WampServer启动3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4.固定公网地址访问 前言 Wamp 是一个 Windows系统下的 Apache PHP Mysql 集成安装环境&#xff0c;是一组常用来…

华为配置WDS背靠背业务示例

配置WDS背靠背业务示例 组网图形 图1 配置WDS背靠背组网示意图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 在某些企业网络中&#xff0c;有线网络部署受施工条件的限制&#xff0c;需要连接的网络之间有障碍物或传输距离较远&#xff0c;AP无法全…

这家宠物品牌的内容运营怎么做的?太好玩儿了吧

养宠的朋友应该多多少少对“诚实一口”这个牌子有所耳闻&#xff0c;2018年诚实一口品牌正式立项&#xff0c;虽然不算经典品牌&#xff0c;但在国内也是小有名气的宠物品牌。今天媒介盒子想和大家聊的不是产品&#xff0c;而是想聊聊作为成立时间不长的国产宠粮品牌是如何凭借…

5.4 内容管理模块 - 课程搜索

5.4 内容管理模块 - 课程搜索 文章目录 5.4 内容管理模块 - 课程搜索一、快速入门1.1 需求分析1.2 业务流程1.3 准备环境1.3.1 搭建 elasticsearch1.3.2 索引 概念 1.4 课程信息索引同步1.4.1 技术方案 一、快速入门 本项目使用elasticsearch作为索引及搜索服务 课程如果发布之…

Sora抢饭碗!好莱坞大亨停止,8亿美元投资

好莱坞消息&#xff0c;著名演员、影视投资人Tyler Perry在看到OpenAI最新发布的文生视频模型Sora后&#xff0c;停止了8亿&#xff08;约57亿元&#xff09;美元的投资。 该投资项目位于亚特兰大&#xff0c;本来要扩展十几个摄影棚用于影视剧的拍摄&#xff08;类似横店影视…

大学开学季,创业入局做校园外卖,这些新的运营思路可以参考

在大学生的学习、生活和消费中&#xff0c;高校已经形成了具有独特属性的市场。这个市场既具有一般市场的特点&#xff0c;同时也有学校特有的一些特点。校园生活服务平台的商业模式就是在互联网发展的背景下出现的&#xff0c;并且已经变得非常成熟和稳定。 就校园外卖而言&a…

Java+SpringBoot+Vue+MySQL:疫情隔离酒店管理的全面技术解决方案

✍✍计算机毕业编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java、…

【云原生】Spring Cloud Gateway的底层原理与实践方法探究

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Spring 狂野之旅&#xff1a;从入门到入魔》 &#x1f680; 本…

切换Linux中的gcc版本

一、允许在系统中并行安装多个软件版本 命令1&#xff1a; yum -y install centos-release-scl 二、安装GCC 8及相关工具 命令2&#xff1a; yum -y install devtoolset-8-gcc devtoolset-8-gcc-c devtoolset-8-binutils 三、将系统中的默认shell环境切换到与devtool…

如何在Win系统搭建Oracle数据库并实现远程访问【内网穿透】

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 前言 Oracle&#xff0c;是甲骨文公司的一款关系…

Flink代码单词统计 ---批处理

flatMap&#xff1a;一对多转换操作&#xff0c;输入句子&#xff0c;输出分词后的每个词groupBy&#xff1a;按Key分组&#xff0c;0代表选择第1列作为Keysum&#xff1a;求和&#xff0c;1代表按照第2列进行累加print&#xff1a;打印最终结果 1.WordCount代码编写 需求&am…

js设计模式:路由模式

作用: 业务开发时,路由这个概念无论对于前后端来说肯定是不可缺少的 前端的vue-router就是很经典的路由模式 示例: //这里模拟实现一个vueclass Vue{constructor(options){Object.keys(options).forEach(item>{this[item] options[item]})}$mount(node){console.log(挂载…

基础知识常见算法识别

特征值识别 很多常见的算法&#xff0c;如AES、DES等&#xff0c;在运算过程中会使用一些常量&#xff0c;而为了提高运算效率&#xff0c;这些常量往往被硬编码在程序中 通过识别这些特征值&#xff0c;可以对算法进行一个大致判断 算法特征值&#xff08;无特殊说明为十六…

Web3的奇迹:数字世界的新篇章

在数字化时代的潮流中&#xff0c;Web3正以其令人振奋的潜力和前景引领着我们进入一个全新的数字时代。作为互联网的下一代&#xff0c;Web3将重新定义我们对数字世界的认知和体验&#xff0c;为我们带来无限的可能性和奇迹。本文将深入探讨Web3的重要性、核心特征以及未来展望…

智能美颜引领短视频创作风潮:探秘美颜SDK技术背后的创新

美颜技术不仅改善了用户的拍摄体验&#xff0c;还推动了短视频创作的风潮。本文将深入探讨智能美颜在短视频创作中的应用&#xff0c;以及美颜SDK技术背后的创新。 一、短视频时代的美颜潮流 随着短视频应用的普及&#xff0c;用户对于视频质量的要求也越来越高。然而&#…