类和对象(下)(二)

news2024/10/3 8:16:48

类和对象(下)(二)

  • 1.友元
    • 1.1友元函数
    • 1.2友元类
  • 2.内部类
  • 3.拷贝对象时的一些编译器优化(vs2022)

🌟🌟hello,各位读者大大们你们好呀🌟🌟
🚀🚀系列专栏:【C++的学习】
📝📝本篇内容:友元;内部类;拷贝对象时的一些编译器优化(vs2022)
⬆⬆⬆⬆上一篇:类和对象(下)(一)
💖💖作者简介:轩情吖,请多多指教(> •̀֊•́ ) ̖́-

1.友元

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

1.1友元函数

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

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class Date
{
friend void Print(Date& d);//声明友元函数
public:
	Date(int year=1, int month=1, int day=1)
		:
		_day(day),
		_year(year),
		_month(month)
	   {}
private:
	int _year;
	int _month;
	int _day;
};
void Print(Date& d)
{
	cout << d._year << "-" << d._month << "-" << d._day << endl;//可以直接突破类的访问限定符
}
int main()
{
	Date d1(2023, 2, 13);
	Print(d1);
	return 0;
}

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

1.2友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
友元关系是单向的,不具有交换性
友元关系不能传递
如果C是B的友元,B是A的友元,则不能说明C是A的友元
友元关系不能继承

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class 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;
};

class Date
{
public:
	Date(int year=0,int month=0,int day=0)
		:_year(year),
		_month(month),
		_day(day),
		_t(15,2,10)
	{}
	void Print()
	{
		cout << _t._hour << ":" << _t._minute << ":" << _t._second << endl;//可以突破访问限定符访问
	}

private:
	int _year;
	int _month;
	int _day;
	Time _t;
};
int main()
{
	Date().Print();
	return 0;
}

2.内部类

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

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class Date
{
public:
	Date(int year=0,int month=0,int day=0)
		:_year(year),
		_month(month),
		_day(day)
	{}
	class 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;
	};
private:
	int _year;
	int _month;
	int _day;
};
int main()
{



	return 0;
}

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

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class Date
{
public:
	Date(int year=0,int month=0,int day=0)
		:_year(year),
		_month(month),
		_day(day)
	{}
	class Time
	{
	public:
		Time(int hour = 0, int minute = 0, int second = 0)
			:_hour(hour),
			_minute(minute),
			_second(second)
		{}
		void Print(const Date& d)
		{
			cout << d._year << "-" << d._month << "-" << d._day << endl;//内部类是外部类的友元
		}
	private:
		int _hour;
		int _minute;
		int _second;
	};
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d(2023, 2, 13);
	Date::Time().Print(d);//Time受Date的类域限制

	return 0;
}

特性:
①内部类可以定义在外部类的public、protected、private都是可以的
②注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class Date
{
public:
	Date(int year=0,int month=0,int day=0)
		:_year(year),
		_month(month),
		_day(day)
	{}
	class Time
	{
	public:
		Time(int hour = 0, int minute = 0, int second = 0)
			:_hour(hour),
			_minute(minute),
			_second(second)
		{}
		static int  Print()
		{
			return count;
		}
	private:
		int _hour;
		int _minute;
		int _second;
	};
private:
	static int count;
	int _year;
	int _month;
	int _day;
};
int Date::count = 20;
int main()
{
	cout << Date::Time::Print() << endl;//Time受Date的类域限制

	return 0;
}

③sizeof(外部类)=外部类,和内部没有任何关系
在这里插入图片描述
依旧用的是上一个代码

3.拷贝对象时的一些编译器优化(vs2022)

在传参和传返回值的过程中,一般编译器会做一些优化,减少对象的拷贝,这个在一些场景下还是非常有用的。

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class Date
{
public:
	Date(void)
		:_year(0),
		_month(0),
		_day(0)
	{
		cout << "构造函数" << endl;
	}

	Date(int i)
	{
		cout << "带参数的构造函数" << endl;
	}

	~Date(void)
	{
		cout << "析构函数" << endl;
	}
	Date(const Date& d)
		:_year(d._year),
		_month(d._month),
		_day(d._day)
	{
		cout << "拷贝构造函数" << endl;
	}
	Date& operator=(const Date& d)
	{
		cout << "赋值运算符重载" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};

void func(Date d)
{}
void func1(const Date& d)
{}
Date fun2(void)
{
	Date a;
	return a;
}
Date func3(void)
{
	return Date();
}
int main()
{
	//Date()._year = 1;//匿名对象是常量
	
	/*Date d1;
	func(d1);//构造+拷贝构造
	*/
	
	//func(Date());//构造+拷贝构造->构造

	//func(1);//构造+拷贝构造->构造
//
	/*Date d1;
	func1(d1);//构造
	*/

   //func1(Date());//构造

	//func1(1);//构造
///
	//fun2();//构造+拷贝构造

	//Date d=fun2();//构造+拷贝构造+拷贝构造->构造+拷贝构造(这里的构造是上面函数里一开始a的构造函数)

	//func3();//构造+拷贝构造->构造

	//Date d=func3();//构造+拷贝构造+拷贝构造->构造	

	Date d;
	d =func3();//构造+构造+拷贝构造+赋值运算符重载->构造+构造+赋值运算符重载

	return 0;
}

大家有兴趣的可以下去试一下,就用我上面的代码,但是要注意并不是所有的编译器都支持或者都会优化的一样,以上是vs2022
对象返回总结:
①接收返回值对象,尽量拷贝构造方式接收,不要赋值接收
②函数中返回对象时,尽量返回匿名对象(匿名对象具有常属性)
函数传参总结:
①尽量使用const &传参

🌸🌸类和对象(下)(二)的知识大概就讲到这里啦,博主后续会继续更新更多C++的相关知识,干货满满,如果觉得博主写的还不错的话,希望各位小伙伴不要吝啬手中的三连哦!你们的支持是博主坚持创作的动力!💪💪

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【c#】反射学习笔记01

c#反射学习01反射学习一、反射原理二、那么我们是如何通过metadata来实现反射呢&#xff1f;三、反射的好处四、反射创建对象&#xff08;利用配置文件简单工厂反射&#xff09;五、反射的黑科技&#xff08;多构造函数调用、破坏单例、创建泛型&#xff09;六、反射调用实例方…

环境配置完整指导——Installing C++ Distributions of PyTorch

目录一、前言二、动手开始做1. 安装cuda 11.42. 安装visual studio 2019 community3. 安装libtorch4. 安装mingw-w645. 配置环境变量6. 打开vscode开始写程序7. 运行程序8. 其他报错信息文章简介&#xff1a;这篇文章用于介绍在windows10 vscode中&#xff0c;跑通如下代码的全…

JavaScript 教程导读

JavaScript 是 Web 的编程语言。所有现代的 HTML 页面都使用 JavaScript&#xff0c;可以用于改进设计、验证表单、检测浏览器、创建cookies等。JavaScript 非常容易学。本教程将教你学习从初级到高级JavaScript知识。JavaScript 在线实例本教程包含了大量的 JavaScript 实例&a…

使用 ONLYOFFICE 转换 API 构建在线文档转换器

文档转换是非常常用、非常有价值的功能&#xff0c;可以帮助我们处理多种文档类型。ONLYOFFICE 编辑器可以轻松地将文档转换为多种格式。在这篇博文中&#xff0c;我们会向您展示&#xff0c;如何构建在 ONLYOFFICE 转换 API 上运行的在线转换器。 关于 ONLYOFFICE 转换 API 使…

傻白探索Chiplet,Design Space Exploration for Chiplet-Assembly-Based Processors(十三)

阅读了Design Space Exploration for Chiplet-Assembly-Based Processors这篇论文&#xff0c;是关于chiplet设计空间探索的&#xff0c;个人感觉核心贡献有两个&#xff1a;1.提出使用整数线性规划算法进行Chiplet的选择&#xff1b;2.基于RE和NRE提出了一个cost模型&#xff…

Map和Set(Java详解)

在开始详解之前&#xff0c;先来看看集合的框架&#xff1a; 可以看到Set实现了Collection接口&#xff0c;而Map又是一个单独存在的接口。 而最下面又分别各有两个类&#xff0c;分别是TreeSet&#xff08;Map&#xff09;和 HashSet&#xff08;Map&#xff09;。 TreeSet&…

CSS---动态向下的循环箭头动画效果

介绍 在移动端的页面中&#xff0c;经常有翻页的提示效果&#xff0c;经常使用向下的箭头动画来提示&#xff1b;一般效果如下所示&#xff1a; 使用到的图片 使用到的图片&#xff0c;就是一个向下的箭头&#xff1b;这里可以下载我的图片使用&#xff1b; 或者也可以使用…

92.【SpringCloud NetFilx】

SpringCloud(一)、这个阶段该如何学习?1.微服务介绍2.面试常见问题(二)、微服务概述1.什么是微服务?2. 微服务与微服务架构(1).微服务(2).微服务架构⭐(3). 微服务优缺点(4). 微服务技术栈有那些&#xff1f;(5). 为什么选择SpringCloud作为微服务架构(三)、SpringCloud入门概…

Python 之 Matplotlib 第一个绘图程序和基本方法

文章目录一、第一个 Matplotlib 绘图程序1. Matplotlib 绘图的基本步骤二、Matplotlib 的基本方法1. 图表名称 plt.title()2. x 轴和 y 轴名称3. 设置 x 轴和 y 轴的刻度4. 显示图表 show()5. 图例 legend()6. 图例的图例位置设置7. 显示每条数据的值 x,y 值的位置一、第一个 M…

LeetCode 61. 旋转链表

原题链接 难度&#xff1a;middle\color{orange}{middle}middle 题目描述 给你一个链表的头节点 headheadhead &#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 kkk 个位置。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], k 2 输出&#xff1a;[4,5,1…

wafw00f源码及流量特征分析

wafw00f介绍 这不是本次的重点&#xff0c;相关介绍及使用方法相信大家已经了解&#xff0c;所以此处就直接引用其开发者对该工具的介绍。 To do its magic, WAFW00F does the following: Sends a normal HTTP request and analyses the response; this identifies a number o…

(考研湖科大教书匠计算机网络)第四章网络层-第三节3、4:划分子网的IPv4地址和无分类IP地址

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;划分子网的IPv4地址&#xff08;1&#xff09;划分子网思想&#xff08;2&#xff09;子网掩码A&#xff1a;概述B&#xff1a;例子C&#xff1a;默…

Django 模型继承问题

文章目录Django 模型继承问题继承出现的情况Meta 和多表继承Meta 和多表继承继承与反向关系指定父类连接字段代理模型QuerySet 仍会返回请求的模型基类约束代理模型管理器代理继承和未托管的模型间的区别多重继承不能用字段名 "hiding"在一个包中管理模型Django 模型…

linux安装极狐gitlab

1. 官网寻找安装方式 不管我们使用任何软件&#xff0c;最靠谱的方式就是查看官方文档。gitlab提供了相应的安装文档&#xff0c;并且有对应的中文文档。地址如下&#xff1a; https://gitlab.cn/install/ 我在这里以CentOS作为安装示例&#xff0c;大家可根据自己的需要选择…

LabVIEW中ActiveX控件、ActiveX服务器和类型库注册

LabVIEW中ActiveX控件、ActiveX服务器和类型库注册如何在计算机上手动注册ActiveX控件&#xff08;.ocx &#xff09;、ActiveX服务器&#xff08;.DLL和.EXE&#xff09;以及类型库&#xff08;.TLB &#xff09;&#xff1f;在LabVIEW中打开ActiveX控件或类的引用时&#xff…

XCP实战系列介绍12-基于Vector_Davinci工具的XCP配置介绍(一)

本文框架 1.概述2. EcuC配置2.1 Pdu添加步骤2.2 配置项说明3. Can 模块配置4. CanIf 模块配置4.1 接收帧的Hardware Receive Object配置4.2 接收帧和发送帧的Pdu配置1.概述 在文章《看了就会的XCP协议介绍》中详细介绍了XCP的协议,在《XCP实战系列介绍01-测量与标定底层逻辑》…

ELK分布式日志收集快速入门-(二)kafka进阶-快速安装可视化管理界面-(单节点部署)

目录安装前准备安装中安装成功安装前准备 安装kafka-参考博客 (10条消息) ELK分布式日志收集快速入门-&#xff08;一&#xff09;-kafka单体篇_康世行的博客-CSDN博客 安装zk 参考博客 (10条消息) 快速搭建-分布式远程调用框架搭建-dubbozookperspringboot demo 演示_康世行的…

Python编程 动态爱心

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.所用库 1.random简介 2.math 简介 3.tkinter库的简介 二.实际图 三.…

OKR之剑·实战篇06:OKR致胜法宝-氛围业绩双轮驱动(下)

作者&#xff1a;vivo 互联网平台产品研发团队 本文是《OKR 之剑》系列之实战第 6 篇—— 本文介绍团队营造氛围的方法与实践、在业绩方面的探索与输出&#xff0c;在两方面分别总结了一些经验分享给大家。 一、我们营造氛围的方法与实践 先说说氛围。组织氛围的提出者库尔…

10分钟学会数据库压力测试,你敢信?

目录 前言 查看数据库版本 下载驱动&#xff1a; 菜单路径 配置 Variable Name Bound to Pool模块配置 Connection pool configuration模块配置 Database Connection Configuration模块配置 菜单路径 Variable Name Bound to Pool 脚本结构 脚本&#xff08;执行查询…