【C++】类与对象—— 初始化列表 、static 静态成员、

news2024/9/23 17:16:34

在这里插入图片描述

类与对象

  • 1 再谈构造函数
    • 1.1 构造函数体赋值
    • 1.2 初始化列表
      • 语法:
      • 建议:
      • 初始化顺序:
      • 注意:
    • 1.3 explicit关键字
  • 2 static 静态成员
    • 2.1 概念
    • 2.2 声明成员变量
    • 2.3 使用类的静态成员
    • 2.4 定义静态成员
    • 总结
  • Thanks♪(・ω・)ノ谢谢阅读!!!
  • 下一篇文章见!!!

1 再谈构造函数

1.1 构造函数体赋值

在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值,以我们之前实现的Date类对象为例。

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

虽然上述构造函数调用的时候,对象中成员变量都有一个初始值了,但是不能将其成为对象中成员变量的初始化,构造函数中语句只能将其成为赋初值,不能叫做初始化。因为初始化只能初始化一次,而构造函数可以多次赋值。进而我们有了初始化列表的概念。

1.2 初始化列表

语法:

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

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 {
private:
	int a;
};
class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
		
	}

private:
	const int _year;
	int& _month;
	int _day;
	A a;
};
int main(){
	const Date a1(2024,2,24);

	return 0;
}

来看看报错:
在这里插入图片描述
显然我们需要初始化来帮助我们解决这些问题。
在很多类中初始化和赋值的区别事关底层效率的问题:前者直接初始化数据成员,后者则先初始化再赋值。除了效率问题外更重要的是,一些数据成员必须初始化。所以一般建议养成使用初始化列表的习惯,这样可以避免某些意想不到的编译错误,特别是遇到类包含构造函数初始值的成员时。

初始化顺序:

显然在构造函数中每个成员只能出现一次。否则给同一个成员赋两个不同初始值有什么意义呢?
需要注意的是初始化列表不限定初始化的执行顺序,因为成员初始化的顺序与他们在类出现顺序一致,第一个成员先初始化,然后第二个,以此类推,因此构造函数初始化列表的前后位置并不影响实际的初始化顺序。
但是下面这个例子不同:

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

我们想要两个输出 1 1 ,但是程序实际输出了:
在这里插入图片描述
这就是因为初始化顺序的问题了,因为成员_a2在_a1前,所以先对_a2初始化,就造成了随机值。

注意:

  1. 每个成员变量在初始化列表中只能出现一次(初始化只能一次)
  2. 类中包括以下成员,必须在初始化列表进行初始化 :
    引用成员变量
    const成员变量
    自定义类型成员(并且该类没有默认构造函数时)
  3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化
  4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。

1.3 explicit关键字

构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。

class Date
{
public:
// 1. 单参构造函数,没有使用explicit修饰,具有类型转换作用
// explicit修饰构造函数,禁止类型转换---explicit去掉之后,代码可以通过编译
   explicit Date(int year)
   	:_year(year)
   	{}
private:
   int _year;
   int _month;
   int _day;
};
void Test()
{
   	Date d1(2022);
   // 用一个整形变量给日期类型对象赋值
   // 实际编译器背后会用2023构造一个无名对象,
   //最后用无名对象给d1对象进行赋值

}
 class Date
{
public:
// 2. 虽然有多个参数,但是创建对象时后两个参数可以不传递,
//没有使用explicit修饰,具有类型转换作用
// explicit修饰构造函数,禁止类型转换
		explicit Date(int year, int month = 1, int day = 1)
			: _year(year)
			, _month(month)
			, _day(day)
			{}

		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);
// 用一个整形变量给日期类型对象赋值
// 实际编译器背后会用2023构造一个无名对象,
//最后用无名对象给d1对象进行赋值
		d1 = 2023;
// 将 1 屏蔽掉,2放开时则编译失败,因为explicit修饰构造函数,
//禁止了单参构造函数类型转换的作用
}

由于上述代码可读性不是很好,所以一般单参数的类构造都要使用explicit修饰。

2 static 静态成员

有时候类需要一些成员与类本身直接相关,而不是与类的各个对象保持联系。
例如,一个银行账户类对象可能需要一个数据成员来表示当前基准利率。在此例中,我们希望利率与类关联,而不是与类的每个对象关联。从实现效率的角度来看,没必要每个对象都储存利率信息。而且更加重要的是,一旦利率浮动,我们希望所有对象都可以使用新值。所以我们引入静态成员的概念。

2.1 概念

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化

2.2 声明成员变量

我们通过在成员的声明之前加入关键字 static 就可以创建,和其他成员一样,静态成员也是可以被 public 或 private的。静态成员变量的类型可以是常量,引用,指针,类类型等。
并且,静态成员函数也不与任何对象绑定在一起,他们不包含this指针。作为结果,静态成员函数不能声明成const 的而且我们也不能在static 函数体内使用this指针。这一限制及适用于this的显式使用,也对调用非静态成员的隐式使用有效。

2.3 使用类的静态成员

使用时我们通过作用域运算符直接访问静态成员。
虽然静态成员不属于类的某个对象,但是我们依然可以使用类的对象、引用、或者指针来访问静态成员。如下:

class Date
{
public:
	Date(int year, int month, int day)
	:_year(year)
	,_month(month)
	,_day(day)
	{ }
static void count();
private:
	int _year;
	int _month;
	int _day;
};
void count(){
}int main(){
	Date d1;
	Date* d2 = &d1; 
	d2->count();
	d1.count();
	return 0;
}

2.4 定义静态成员

和其他成员函数一样,我们既可以在类内部也可以在外部定义。当在类外定义时,不需要重复写 static 关键字,该关键字只出现在类内部的声明语句。
和类的所有成员一样,当我们指向类外部的静态成员时,必须指明成员所属的类名。static 关键字则只出现在类内部的声明语句中
要确保对象只定义一次,最好的办法就是把静态成员的定义与其他非内联函数的定义于同一个文件中。

总结

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

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

下一篇文章见!!!

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

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

相关文章

提高自定义词汇表上的 RAG 性能

原文地址&#xff1a;improve-rag-performance-on-custom-vocabulary Code&#xff1a;Improve RAG performance on custom vocabulary.ipynb 2024 年 2 月 9 日 糟糕的检索系统会导致混乱、沮丧和幻觉。 新的嵌入模型比以往更加强大。我们根据 MTEB 等基准对其进行了全面评…

go 1.18 不同目录package引用问题

go 1.18开始使用module了 不同的package在vs code中引用的话 需要先开启 是Go1.11版本之后 推出的版本管理工具 有点类似java的 maven工具 可以引入依赖使用 go env -w GO111MODULEon 先把这个打开 然后在创建的vs code工作目录下 执行 module gomdoule module 模块名 会生…

前后端分离Vue+nodejs校园论坛bbs系统x450z

开发语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode本论文拟采用计算机技术设计并开发的论坛bbs系统&#xff0c;主要是为用户提供服务。使得用户可以在系统上查看帖子信息、签到积分等…

unity hub (第一部)初学配置

1、安装Unity Hub 2、设置中文 3、安装编辑器 4、新建项目 5、新建完成后进入编辑器 6、 编辑器设置中文 editPreferencesLanguages选择中文

数学建模资料分享

1. 往年各赛题的优秀论文 可以用来参考一下论文是怎么写的。参考论文的结构&#xff0c;格式&#xff0c;思路等等。 链接&#xff1a;https://pan.baidu.com/s/1WG2t4-x9MjtaSgkq4ue5AQ?pwdnlzx 提取码&#xff1a;nlzx --来自百度网盘超级会员V4的分享 2.论文模板 链接&a…

学习JAVA的第二天(基础)

目录 基本概念 关键字 class关键字 字面量 练习 变量 定义格式 变量使用 数据类型 基本数据类型 标识符 命名规则 键盘录入 1.导包 2.创建对象 3.接受数据 运算符 算术运算符 练习 隐式转换&#xff08;自动类型提升&#xff09; 强制转换 自增自减运算符 …

众安保险基于Apache SeaTunnel的生产应用实践

*> 文&#xff5c;曾力 众安保险大数据开发高级专家 编辑整理&#xff5c; 曾辉* 前言 众安保险从2023年4月就开始了数据集成服务的预研工作&#xff0c;意在通过该服务解决当前数据同步场景下的两大痛点&#xff0c;服务化能力薄弱和无分布式同步能力。我们对多种开源数据…

【Java程序设计】【C00291】基于Springboot的网上图书商城(有论文)

基于Springboot的网上图书商城&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的网上图书商城 本系统分为系统功能模块、管理员功能模块以及卖家功能模块。 系统功能模块&#xff1a;在系统首页可以查看首页、图书…

社区志愿者齐心协力,为社区居民营造温馨和谐环境

近日&#xff0c;在我们的社区里&#xff0c;一场温暖而有力的力量正在悄然兴起。一群热心居民自发组织成为社区志愿者团队&#xff0c;积极投身于服务社区的各项活动中&#xff0c;为居民们营造了一个温馨和谐的生活环境。 在每个周末的清晨&#xff0c;志愿者们早早地聚集在社…

匿名+有名管道

管道 相关概念 4种情况 正常情况&#xff0c;如果管道没有数据&#xff0c;读端陷入等待&#xff0c;直到有数据才能唤醒正常情况&#xff0c;如果管道被写满&#xff0c;写端陷入等待&#xff0c;直到有空间才能唤醒写段关闭&#xff0c;读端一直读取&#xff0c;read返回0…

Linux Android USB gadget(从设备驱动)

Linux Android USB gadget 一:Linux usb gadget 与 Android Composite Gadget二:原生方式和Android方式如何配置函数调用逻辑内核配置原生驱动android驱动三:mass_storage配置虚拟化U盘四:遍历usb设备五:adb usb判断usb设备为adb获取adb配置信息adb设备序列号发送与接收《Linux…

一键生成PDF即刻呈现:轻松创建无忧体验

在信息爆炸的时代&#xff0c;我们每天都在与各种文件、资料打交道。无论是工作中的报告、合同&#xff0c;还是学习中的笔记、论文&#xff0c;如何高效、安全地管理这些珍贵的资料&#xff0c;成为了我们迫切的需求。幸运的是&#xff0c;随着科技的发展&#xff0c;我们不再…

在Linux系统上实现高效安装与部署环境的全方位指南

前言 在数字化时代&#xff0c;Linux操作系统以其高度的灵活性、安全性和稳定性&#xff0c;成为了众多开发者和系统管理员的首选。然而&#xff0c;要想充分发挥Linux系统的优势&#xff0c;一个高效、稳定、易于管理的安装与部署环境至关重要。本文旨在为广大Linux爱好者、初…

XSS原理和攻防

Cross Site Scripting:跨站脚本攻击 用户提交的数据中可以构造恶意代码&#xff0c;并且执行&#xff0c;从而实现窃取用户信息等攻击 攻击&#xff1a; 防御&#xff1a; 1.对输入进行过滤&#xff0c;对输出进行编码 2.cookie设置http-only

计算机网络面经_体系结构一文说清

编辑&#xff1a;平平无奇的羊 目录 基础 1. 计算机网络结构体系 三种模型之间的区别&#xff1a; 如何背诵&#xff1a; 进阶 OSI七层模型&#xff1a; TCP/IP四层模型&#xff1a; TCP/IP五层模型 总结 字节实习生为大家带来的是计算机网络面经系列博文&#xff0c;由浅…

【Flink集群RPC通讯机制(二)】创建AkkaRpcService、启动RPC服务、实现相互通信

文章目录 零. RpcService服务概述1. AkkaRpcService的创建和初始化2.通过AkkaRpcService初始化RpcServer3. ResourceManager中RPC服务的启动4. 实现相互通讯能力 零. RpcService服务概述 RpcService负责创建和启动Flink集群环境中RpcEndpoint组件的RpcServer&#xff0c;且Rpc…

SQL-Labs靶场“46-50”关通关教程

君衍. 一、四十六关 ORDER BY数字型注入1、源码分析2、rand()盲注3、if语句盲注4、时间盲注5、报错注入6、Limit注入 二、四十七关 ORDER BY单引号报错注入1、源码分析2、报错注入3、时间盲注 三、四十八关 ODRER BY数字型盲注1、源码分析2、rand()盲注3、if语句盲注4、时间盲注…

2.openEuler概述及安装指南(二)

openEuler OECA认证辅导&#xff0c;标红的文字为学习重点和考点。 如果需要做实验&#xff0c;建议下载麒麟信安、银河麒麟、统信等具有图形化的操作系统&#xff0c;其安装与openeuler基本一致。 1.安装过程及配置 使用光盘引导安装&#xff1a; 此处以光盘安装为例介绍安装…

c语言的数据结构:找环状链表入口处

一起<(&#xffe3;︶&#xffe3;)↗[GO!] 1.如何判断一个链表是否有环 思路:设定两个快慢指针fast和slow,fast每次走两个结点,slow每次走一个节点 如果fast指针遇到了Null,那么这个链表没有环,如果fast和slow可以相遇,则代表这个链表有环 代码如下 N:fast先进环,slow后…

【Azure 架构师学习笔记】- Azure Databricks (8) --UC架构简介

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Databricks】系列。 接上文 【Azure 架构师学习笔记】- Azure Databricks (7) --Unity Catalog(UC) 基本概念和组件 前言 UC 简单来说&#xff0c;就是管理两样东西&#xff1a;用户和元存储。 用户管理 所有Databri…