C嘎嘎之类和对象下

news2024/12/24 22:17:44

> 作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等
> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:了解顺序表和链表的利弊,能在不同的题型中采用不同的表,对链表的理解更加深刻。

> 毒鸡汤:彪悍的人生,不需要解释。只要你按时达到目的地,很少有人在乎你开的是奔驰还是拖拉机。
> 望小伙伴们点赞👍收藏✨加关注哟💕💕 

🌟前言

        本篇博客书接上文,在类和对象中,我们掌握c++的初始化和销毁,运用拷贝构造和赋值重载,不知道小伙伴们看了我写的日期类的实现,在这篇博客中对类和对象的是一个很好复习,今天也是类和对象最后一篇,望大家坚持坚持

主体  

        咱们从五大板块学习,再谈构造函数,Static成员 ,友元 ,内部类,匿名对象当时我们只学了构造函数的70%,今天摊牌了,咱们看看完整的构造函数。



 🌙再谈构造函数

咱们重温构造函数是如何实现的:

  • 💦函数名与类名相同。
  • 💦无返回值。
  • 💦对象实例化时编译器自动调用对应的构造函数。
  • 💦构造函数可以重载。

看下面一个简单的代码:

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

        我可以知道虽然在构造函数中赋值了,但是只能说对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,因此不能说是初始化。所以我们知道它和初始化还是有一定的区别的。 

我们简单的概括为:我们最初学习的初始化只能初始化一次,而构造函数体内可以多次赋值。

那我们就是想初始化构造函数的参数,那该如何捏???

💫初始化列表

        初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。

看下面一个简单的代码:

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


💦每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
💦类中包含以下成员,必须放在初始化列表位置进行初始化:

  • 引用成员变量
  • const成员变量
  • 自定义类型成员(且该类没有默认构造函数时)

💦尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。

💦成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

看下面一个简单的代码:

class A
{
public:
	A(int a)
		:_a(a)
	{}
private:
	int _a;
};

class B
{
public:
	B(int a, int ref)
		:_aobj(a)
		, _ref(ref)
		, _n(10)
	{}
private:
	A _aobj;		// 没有默认构造函数
	int& _ref;		// 引用
	const int _n;   // const 
}


看下面一个有趣的代码:

class A
{
public:
	A(int a)
		:_a1(a)
		, _a2(_a1)
	{}

	void Print() {
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a2;
	int _a1;
};
int main() {
	A aa(1);
	aa.Print();
}
A.输出1  1
B.程序崩溃
C.编译不通过
D.输出1  随机值

结果为:D

        因为:初始化a,后传参,先赋值给_a1,而当到_a2(_a1)时_a1,_a2已经初始化了,所以_a2的值为随机值

💫explicit关键字

        构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用,而咱们explicit为了防止让变量变心,因此就把变量管理死死的,重而达到防止类型转换。

看下面一个简单的代码:

class Date
{
public:
	explicit Date(int year)
		:_year(year)
	{}
	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};
void Test()
{
	Date d1(2022);
}

这样就可以防止类型转化。

🌙Static成员

        声明为static的类成员称为类的静态成员(与C语言中的用法是一样滴而用static修饰的成员变量,称之为静态成员变量,用static修饰的成员函数,称之为静态成员函数



🫥🫥特性

  • 💦静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区
  • 💦静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明
  • 💦类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
  • 💦静态成员函数没有隐藏的this指针,不能访问任何非静态成员
  • 💦静态成员也是类的成员,受public、protected、private 访问限定符的限制

🧐🧐重点

  • 💦静态成员函数是不可以调用非静态成员函数的(因为静态成员函数没有this*)
  • 💦非静态成员函数可以调用类的静态成员函数

🌙友元

        友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,简单来说就是你是我的好朋友,咱们可以一起玩耍,可以去好朋友家玩,没有权限,直接访问,但是在c++中用的比不是很多,因为违背了c++的封装,既然有这块知识点,存在即合理

💫友元函数

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

        用一句简单的话来说友元函数的作用:友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字

咱们看一下下面的代码:

class Date
{
	friend ostream& operator<<(ostream& _cout, const Date& d);
	friend istream& operator>>(istream& _cin, Date& d);
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{
	_cout << d._year << "-" << d._month << "-" << d._day;
	return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{
	_cin >> d._year;
	_cin >> d._month;
	_cin >> d._day;
	return _cin;
}
int main()
{
	Date d;
	cin >> d;
	cout << d << endl;
	return 0;
}


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

💫友元类

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

  • 💦友元关系是单向的,不具有交换性。(比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。)
  • 💦友元关系不能传递。(如果C是B的友元, B是A的友元,则不能说明C时A的友元)
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;
};

🌙内部类

内部类本质上在类中套娃

        概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。
        注意:内部类就是外部类的友元类,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。

特性:

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

🌙匿名对象

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

 🌟结束语

       今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小说手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。

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

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

相关文章

MathType安装激活教程安装后点击exe闪退问题解决

MathType安装 官方下载地址&#xff1a;https://mathtype.org/download/ 1.打开下载好的安装包 2.点击我接受 3.等待。 4.默认C盘路径安装&#xff0c;不要修改&#xff0c;点击确定。 5.等待。 6.点击确定。 7.退出安装&#xff0c;安装完成&#xff01; 8.软件安装后&…

人工智能基础_机器学习020_归一化实战_天池工业蒸汽量项目归一化实战过程_使用sklearn库中的最大最小值归一化和_sklearn库中的Z-score归一化_01---人工智能工作笔记0060

首先我们找到对应的数据,天池蒸汽项目的数据. import pandas as pd 导入文件读取库 import numpy as np 导入数学计算库 df=pd.readcsv(./zhenggi_train.txt,sep=\t) 读取csv文件,这个就是天池的用tab分割的数据 X_train = df . iloc[:,: - 1],我们我们切片,从0列,切片到…

Loki | 数据过期自动删除策略设计

最近使用 Loki 碰到一个比较蛋疼问题&#xff0c;配置日志过期时间&#xff0c;配置这种事情&#xff0c;自然是要参照官方文档了&#xff0c;当时就找到了这个文档&#xff0c;地址&#xff1a; https://github.com/grafana/loki/blob/v1.5.0/docs/operations/storage/retenti…

手写txt模拟数据库简易框架

一.前言 之前学校让我们写控制台饿了么项目&#xff0c;当时进度没有到数据库&#xff0c;所以用的文本文件txt&#xff0c;来模拟数据库的实现&#xff0c;其实本质上就是一个文件读写&#xff0c;但是简单文件读写并不能包含我们想要的功能&#xff0c;例如条件查询&#xff…

【算法秘籍】藏在0和1之间的秘密,助你码出优秀人生

《算法秘籍》双十一 5折购书&#xff0c;就在京东商城 数据结构和算法是计算机科学的基石&#xff0c;是计算机的灵魂&#xff0c;要想成为计算机专业人员&#xff0c;学习和掌握算法是十分必要的。不懂数据结构和算法的人不可能写出效率更高的代码。计算机科学的很多新行业都离…

Discord将切换到临时文件链接以阻止恶意软件传播

导语 Discord是一个广受欢迎的社交平台&#xff0c;但其服务器长期以来一直是恶意活动的温床。为了解决这个问题&#xff0c;Discord决定采取行动&#xff0c;将切换到临时文件链接&#xff0c;以阻止恶意软件的传播。本文将介绍Discord的最新举措&#xff0c;并探讨其对用户安…

C盘清理指南(三)——文件目录更改

各位小伙伴你们好&#xff0c;今天的推送是C盘清理系列的第三期——文件路径更改&#xff0c;分为文件夹路径和软件默认路径两个模块。 一&#xff0e;文件夹路径更改 点击进入C盘&#xff0c;依次点击上方“查看——隐藏的项目”&#xff0c;可以看到C盘中各种隐藏目录。 单击…

kafka微服务学习

消息中间件对比&#xff1a; 1、吞吐、可靠性、性能 Kafka安装 Kafka对于zookeeper是强依赖&#xff0c;保存kafka相关的节点数据&#xff0c;所以安装Kafka之前必须先安装zookeeper Docker安装zookeeper 下载镜像&#xff1a; docker pull zookeeper:3.4.14创建容器 do…

Linux 下最主流的文件系统格式——ext

硬盘分成相同大小的单元&#xff0c;我们称为块&#xff08;Block&#xff09;。一块的大小是扇区大小的整数倍&#xff0c;默认是 4K。在格式化的时候&#xff0c;这个值是可以设定的。 一大块硬盘被分成了一个个小的块&#xff0c;用来存放文件的数据部分。这样一来&#xf…

操作系统 day06(进程控制、原语)

进程控制的概念 原语 怎么实现进程控制—用原语实现 如果不能一气呵成&#xff0c;那么会出现操作系统中的某些关键数据结构信息不统一的情况&#xff0c;这会影响操作系统进行别的管理工作&#xff0c;如下图所示&#xff1a; 原语的原子性怎么实现 正常情况下&#xff…

Source insight 创建工程研读库源码

下载库文件解压 创建工程添加路径 添加文件到工程 同步文件 下载库文件解压 创建工程添加路径 添加文件到工程 同步文件 数据库更新 强制重新分析所有文件仅同步当前源文件 添加和删除文件 自动添加新文件从项目中删除丢失的文件

程序员想要网上接单?那这几点注意事项你可要记好了!不看后悔!

相信网上接单对于程序员来说并不陌生&#xff0c;甚至有些程序员还以此为主业&#xff0c;靠网上接单来增加收入&#xff0c;维持生计&#xff0c;但是你真的确定你懂网上接单的套路吗&#xff1f;你知道网上接单的注意事项吗&#xff1f;这期文章就来盘点一下&#xff0c;无论…

跟着森老师学React Hooks(1)——使用Vite构建React项目

Vite是一款构建工具&#xff0c;对ts有很好的支持&#xff0c;最近也是在前端越来越流行。 以往的React项目的初始化方式大多是通过脚手架create-react-app(本质是webpack)&#xff0c;其实比起Vite来构建&#xff0c;启动会慢一些。 所以这次跟着B站的一个教程&#xff0c;使用…

JavaWeb Day05 前后端请求响应与分层解耦

目录 一、请求与响应 &#xff08;一&#xff09;请求的参数接收 ①数组参数 ②集合参数 ③日期参数 ④json参数 ⑤路径参数 总结 &#xff08;二&#xff09;响应 ①简单文本text ②数组 ③列表 ④同一响应数据格式 ⑤总结 二、三层架构与分层解耦 &#xff0…

Windows下MSYS2下载与安装

下载地址&#xff1a; 官网下载地址 https://www.msys2.org/阿里云镜像下载 https://mirrors.aliyun.com/msys2/distrib/x86_64/https://mirrors.aliyun.com/msys2/distrib/x86_64/msys2-x86_64-20231026.exe?spma2c6h.25603864.0.0.12b92551XW5OSM官网下载 ![官网下载](htt…

程序员怎样才能学好算法,推荐好书送给大家

前言 数据结构和算法是计算机科学的基石&#xff0c;是计算机的灵魂 要想成为计算机专业人员&#xff0c;学习和掌握算法是十分必要的。不懂数据结构和算法的人不可能写出效率更高的代码。计算机科学的很多新行业都离不开数据结构和算法作为基石&#xff0c;比如大数据、人工…

【AICFD案例教程】轴流风扇仿真分析

AICFD是由天洑软件自主研发的通用智能热流体仿真软件&#xff0c;用于高效解决能源动力、船舶海洋、电子设备和车辆运载等领域复杂的流动和传热问题。软件涵盖了从建模、仿真到结果处理完整仿真分析流程&#xff0c;帮助工业企业建立设计、仿真和优化相结合的一体化流程&#x…

Jmeter接口自动化测试操作流程

在企业使用jmeter开展实际的接口自动化测试工具&#xff0c;建议按如下操作流程&#xff0c; 可以使整个接口测试过程更规范&#xff0c;更有效。 接口自动化的流程&#xff1a; 1、获取到接口文档&#xff1a;swagger、word、excel ... 2、熟悉接口文档然后设计测试用例&am…

QT第2课-GUI程序实例分析

GUI程序开发概述 不同的操作系统GUI开发原理相同不同的操作系统GUI SDK 不同 GUI 程序开发原理 GUI程序在运行时会创建一个消息队列系统内核将用户的键盘鼠标操作翻译成对应的程序消息程序在运行过程中需要实时处理队列中的消息当队列中没有消息时&#xff0c;程序将处于停滞…

第23章(上)_索引原理之索引与约束

文章目录 索引索引分类主键选择索引的代价 约束外键约束约束与索引的区别 索引使用场景不要使用索引的场景总结 索引 索引的概念&#xff1a;索引是一种有序的存储结构。索引按照单个或多个列的值进行排序。 索引的目的&#xff1a;提升搜索效率。 索引分类 按照数据结构分为…