c++初始化列表和静态成员

news2024/9/28 1:18:49

文章目录

  • 一、初始化列表
  • 二、静态(static)成员


一、初始化列表

类对于成员变量的赋值有两种方式

  • 函数体内赋值
  • 初始化列表
    函数体内赋值就是直接在构造函数中赋值即可,而初始化列表它是较为特殊的一种方式!
    初始化列表是在构造函数()之后以:开始,然后后面跟要初始化的变量,之后再跟(),括号里面的值或者表达式就是对这个变量的初始化!然后再以,作为分割,之后可以再跟成员变量赋值或者不跟,没有就不用再用逗号分割!
    如下:
    在这里插入图片描述
    为什么要出来初始化列表?函数体内赋值不好吗?

因为有些情况只有初始化列表才能完成!
如:引用、const修饰的、自定义类型(没有默认构造函数)

引用和const都是必须在定义的时候初始化赋值!
在这里插入图片描述
而const 修饰的不在定义的时候初始化,那么就改不了它了,他就是一个随机值了!
而类对象成员变量它的定义不是在类中,类里面仅仅只是对其声明,真正定义是在对象定义之后,对象调用它的构造函数在其初始化列表对其定义,而这些并不是在构造函数函数体内定义,函数厅内赋值仅仅只是对其再次赋值而已!如:成员变量中有自定义类型时,都说它会去自动调用这个自定义类型的构造函数,但是这是建立在它的构造函数是默认构造的前提下,如果不是就不行了!自定义类型成员它的调用是在初始化列表完成的!
成员是引用、const修饰,自定义类型

class stack
{
public:
	stack(int capacity)
	{
		_a = (int*)malloc(sizeof(int) * capacity);
		if (_a == nullptr)
		{
			perror("malloc fail\n");
			exit(-1);
		}

		_top = 0;
		_capacity = capacity;
	}

private:
	int* _a;
	int _top;
	int _capacity;
};

class B
{
public:
	B(int& a,int b = 2)
		:_a(a)
		,_b(b)
		,_st(10)
	{
	}

private:
	int& _a;
	const int _b;
	stack _st;

};

在这里插入图片描述
并且不能将其写在函数体内,只能写在初始化列表!
在这里插入图片描述
类成员变量的定义是在初始化列表定义的,他只是在类里面声明而已,所有这三类只能写在初始化列表!
而当不在初始化列表显示写出时,其实它也是定义好了的!我没在函数体内给它赋值,那么就是每给它赋值,它的值就是随机值!
在这里插入图片描述
当初始化列表没有写出时,其实它们还是照样要走初始化列表完成定义!
既然初始化这么神奇,那么为什么不一开始直接用初始化列表?
因为初始化列表不能完成全部的工作,有些时候赋值完成之后还要检查,或者给空间赋值
初始化的!
如:

class BB
{
public:
	BB(int capacity=4)
		:_a((int*)malloc(sizeof(int)* capacity))
		,_top(0)
		,_capacity(capacity)
	{
		if (_a == nullptr)
		{
			perror("malloc fail\n");
			exit(-1);
		}

		memset(_a, 0, sizeof(int) * _capacity);
	}

private:
	int* _a;
	int _top;
	int _capacity;
};

这段代码它仅仅只是在初始化列表完成初始化还是不够的,还需要检查_a开的空间是否成功,这时在初始化列表中就无法完成,需要在函数体内完成!

还有就是动态开辟一个二维数组,只是初始化列表并不能完成,需要在函数体内完成!

class AA
{
public:
	AA(int row=10,int col = 5)
	{
		_a = (int**)malloc(sizeof(int*) * row);
		if (_a == nullptr)
		{
			perror("malloc fail\n");
			exit(-1);
		}
		for (int i = 0; i < row; i++)
		{
			_a[i] = (int*)malloc(sizeof(int) * col);
			if (_a[i] == nullptr)
			{
				perror("malloc fail\n");
				exit(-1);
			}
		}
	}

private:
	int** _a;
};

动态开辟一个二维数组,是先将行开辟出来,然后再每一行有多少列开辟出来这样在初始化列表是无法完成的!需要在函数体内完成!就这样说吧,初始化列表能完成95%的事情但是剩下的5%需要在函数体内完成!
初始化列表初始化顺序与声明应一致
初始化列表在初始化声明的成员变量时,是按照声明的顺序进行初始化的!所有在初始化列表中,建议初始化顺序与声明顺序一致!

class C
{
public:
	C(int a)
		:_a(a)
		,_b(_a)
	{}

	void Print()
	{
		cout << _a << " " << _b << endl;
	}

private:
	int _b;
	int  _a;
	
};

int main()
{
	C c(1);
	c.Print();
	return 0;
}

这段程序是没有保持一致的,它运行出来的结果如下:
在这里插入图片描述

二、静态(static)成员

先来看一个场景,场景需求是统计一个类创建了多少对象,其实创建了多少对象,在创建对象之后救护调用一次构造,所以可以定义一个全局变量cnt来统计,然后在构造函数中++,拷贝构造之中也要++,因为有时是以一个已经存在对象初始化另一个不存在的对象!
全局变量统计类创建了多少个对象

int cnt = 0;
class Count
{
public:
	Count()
	{
		cnt++;
	}

	~Count()
	{
		cnt--;
	}
	
};

Count c1;

void fun()
{
	Count c2;
	cout << __LINE__ << " " << cnt << endl;
	
}

int main()
{
	cout << __LINE__ << " "<<cnt << endl;

	Count c;
	cout << __LINE__ << " " << cnt << endl;
	fun();
	cout << __LINE__ << " " << cnt << endl;
	
	return 0;
}

在这里插入图片描述
其中的__LINE__是显示文件行
但是定义了这个全局变量,在任意位置都能修改它!这样不安全,为了不能修改它,将其封装到类中使其成为类成员变量!
但是它要与普通成员变量不同,将其弄成静态成员变量!在前面加static
那么普通成员变量与静态成员变量有什么区别?

普通成员变量:属于每一个类对象,存储在类对象中
静态成员变量:属于类,属于每一个类共享,存储在静态区!它不在初始化列表定义,因为它存储在静态区,将其定义在类外边!

但是这样它是私有成员变量,访问不了它,要访问它,可以将其弄成公有成员变量或者写一个公有函数获取它!这个成员函数也可以设置为静态成员函数!静态成员函数无this指针,它不能访问非静态成员变量或非静态成员函数!
静态成员统计类创建了多少个对象

class Count
{
public:
	Count()
	{
		cnt++;
	}

	~Count()
	{
		cnt--;
	}
	static int Getcnt()
	{
		return cnt;
	}
private:
	static int cnt;
};

int Count::cnt = 0;
Count c1;

void fun()
{
	Count c2;
	cout << __LINE__ <<" "<< Count::Getcnt() << endl;
}

int main()
{
	cout << __LINE__ << " " << Count::Getcnt() << endl;

	Count c;
	cout << __LINE__ << " " << Count::Getcnt() << endl;

	fun();
	cout << __LINE__ << " " << Count::Getcnt() << endl;
	return 0;
}

只是将其弄成了静态成员函数之后,在这个函数体内无法调用类中的非静态成员函数,并且不能访问类中非静态成员变量!因为没有this指针!但是非静态成员函数可以调用静态成员函数和访问静态成员变量!
凡是经由static 修饰定义的都是存储在静态区去了,它的定义也就在类之外定义了!

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

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

相关文章

查询穿梭框实现

技术栈&#xff1a; 使用vue3 的composition api 和 tsx 进行开发 一、需求描述 点击编辑&#xff0c;显示穿梭框&#xff1a; 可将左侧维度拖动至右侧&#xff0c;已选维度可上下拖动调整顺序。 二、需求分析 1、状态传递过程 我们首先来分析一下&#xff0c;整个流程中的…

魔改xxl-job,彻底告别手动配置任务!自动注册xxljob定时任务

xxl-job是一款非常优秀的任务调度中间件&#xff0c;轻量级、使用简单、支持分布式等优点&#xff0c;让它广泛应用在我们的项目中&#xff0c;解决了不少定时任务的调度问题。 我们都知道&#xff0c;在使用过程中需要先到xxl-job的任务调度中心页面上&#xff0c;配置执行器…

WiFi模块测试|高通QCA9531方案WiFi模块网页配置说明-SKW99/SKW100

本篇以高通QCA9531方案无线路由WiFi模块SKW99为例&#xff0c;简单介绍 高通方案无线路由WiFi模块的软件使用。友情提示&#xff1a;多图&#xff0c;请在WiFi环境下阅读。 以SKW99为例&#xff0c;在SKW99规格书找到模块系统框图、PIN脚图及各个PIN脚的描述定义&#xff1b;之…

AutoSAR系列讲解(入门篇)3.4-RTE对Ports的支撑(下)

一、C/S接口的实现 之前在第二章AppL中讲过了C/S接口&#xff0c;这里再更加深入的说明一下其实现的原理&#xff1a;首先&#xff0c;C/S接口就是客户/服务接口&#xff0c;这个接口就是客户来调用服务 端的操作的一个接口。也就是我写着写着&#xff0c;发现我想要调用一个函…

【Figma技巧】布尔变量控制图层显隐

用2023年6月22日更新的Figma最新功能&#xff0c;实现按钮控制图层显隐的交互。 实现效果 步骤 1. 创建本地变量 点击右侧面板中的Local variables弹出变量面板&#xff0c;点击底部Create variable按钮&#xff0c;创建一个Boolean布尔变量。 本案例中&#xff0c;我需要分…

从0开始Jmeter接口测试实战

在之前的文章中给大家介绍过接口测试文档和接口测试用例示例&#xff0c;本文基于Jmeter工具给大家介绍一下如何实现接口测试用例&#xff1a;包括发起Http请求&#xff0c;绕过登陆&#xff0c;验证响应。JMeter是Apache组织开发的基于Java的压力测试工具。具有开源免费、框架…

Python|Pyppeteer操作浏览器,弹出文件选择框,实现自动选择“指定文件”(14)

前言 本文是该专栏的第14篇,结合优质项目案例持续分享Pyppeteer的干货知识,记得关注。 使用pyppeyeer操作浏览器的时候,可能有时候会遇到这样的情况,如下图所示: 通过程序脚本自动点击某个按钮之后,触发一个弹出框,需要输入对应的文件路径。经验丰富的同学,可能会想到…

深入浅出 - 单例模式

博主介绍&#xff1a; ✌博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家✌ Java知识图谱点击链接&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; &#x1f495;&#x1f495; 感兴趣的同学可以收…

【MySQL】幽深不可测,登此方觉心

详解Mysql安装教程 一、MySQL基础 1、MySQL是什么? MySQL是一种用关系型数据库管理系统的软件。它是一种开源数据库&#xff0c;可以利用它来存储、管理和访问各种类型的数据。MySQL可用于多种应用程序&#xff0c;包括网站、电子商务系统、移动应用程序、企业级应用程序等…

Clickhouse物化视图原理和使用详解

前言 ClickHouse广泛用于用户和系统日志查询场景中&#xff0c;主要针对于OLAP场景&#xff0c;为业务方提供稳定高效的查询服务。在业务场景下&#xff0c;数据以不同的格式、途径写入到clickhouse。用传统JOIN方式查询海量数据&#xff0c;通常有如下痛点: 每个查询的代码冗…

【Java】ConcurrentHashMap1.8源码保姆级解析

目录 ConcurrentHashMap 1.8的优化 初始化流程 扩容流程 读取数据流程 计数器的实现 ConcurrentHashMap 1.8的优化 存储结构的优化 数组链表 -> 数组链表红黑树 写数据加锁的优化 扩容的优化&#xff08;协助优化&#xff09; 计数器的优化 LongAddr -> Cell[] 分…

力扣算法练习(二)

主要参考自力扣官网解法 1.最长回文子串(5) 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s "babad" 输出&#xff1a;"bab"…

【Java】JVM学习(七)

JVM调优 堆空间如何设置 在分代模型中&#xff0c;各分区的大小对GC的性能影响很大。如何将各分区调整到合适的大小&#xff0c;分析活跃数据的大小是很好的切入点。 活跃数据的大小&#xff1a;应用程序稳定运行时长期存活对象在堆中占用的空间大小&#xff0c;也就是Full …

Git安装及使用图文教程详解(附带安装文件)

Git安装及使用图文教程详解&#xff08;附带安装文件&#xff09; 原创&#xff1a;丶无殇  2023-06-26 文章目录 下载安装下载安装验证安装成功版本查看 基础指令Git常用指令【首次必须】设置签名用户、邮箱1.初始化本地仓库2.查看本地库状态3.创建文件4.添加文件至暂存区5…

【DCT变换】Python矩阵运算实现DCT变换

一、前言 DCT变换&#xff08;离散余弦变换&#xff09; 是数字图像处理过程中广泛采用的一种操作&#xff0c;用于将空域的图像转换为频域表示&#xff0c;从而能够更有效地进行压缩、滤波和特征提取等处理。它在许多应用领域中发挥着重要的作用&#xff0c;尤其在图像和视频…

感知机(Perceptron)的原理及实现

1.感知机&#xff08;Perceptron&#xff09;的原理及实现 声明&#xff1a;笔记来源于《白话机器学习的数学》 感知机是接受多个输入后将每个值与各自权重相乘&#xff0c;最后输出总和的模型。 单层感知机因过于简单&#xff0c;无法应用于实际问题&#xff0c;但它是神经网络…

一文让你搞定接口测试

一、什么是接口测试&#xff1f; 所谓接口&#xff0c;是指同一个系统中模块与模块间的数据传递接口、前后端交互、跨系统跨平台跨数据库的对接。而接口测试&#xff0c;则是通过接口的不同情况下的输入&#xff0c;去对比输出&#xff0c;看看是否满足接口规范所规定的功能、…

二叉树知识小结

思维导图&#xff1a; 一&#xff0c;树 树&#xff0c;这是一种对计算机里的某种数据结构的形象比喻。比如这种: 这种&#xff1a; 这种&#xff1a; 这几种都是树形结构。在百度百科中对树形结构的定义如下&#xff1a; 树形结构指的是数据元素之间存在着“一对多”的树形关系…

津津乐道设计模式 - 建造者模式详解(教你如何构造一个专属女友)

&#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Micro麦可乐的博客 &#x1f425;《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程&#xff0c;入门到实战 &#x1f33a;《RabbitMQ》…

接口测试断言详解(Jmeter)

接口测试是目前最主流的自动化测试手段&#xff0c;它向服务器发送请求&#xff0c;接收和解析响应结果&#xff0c;通过验证响应报文是否满足需求规约来验证系统逻辑正确性。接口的响应类型通过Content-Type指定&#xff0c;常见的响应类型有&#xff1a; • text/html &…