C++ 类和对象(类型转换、static成员)

news2024/11/29 3:42:37

目录

一、前言

二、正文

1.隐式类型转换

1.1隐式类型转换的使用

2.static成员

2.1 static 成员的使用

2.1.1static修辞成员变量

2.1.2 static修辞成员函数

三、结语


一、前言

大家好,我们又见面了。昨天我们已经分享了初始化列表:https://blog.csdn.net/yiqingaa/article/details/144020182

今天让我们分享C++新知识——类型转换、static成员吧

二、正文

1.隐式类型转换

  •  ++支持内置类型隐式类型转换为类类型对象,需要有相关内置类型为参数的构造函数。
  • 构造函数前面加explicit就不再支持隐式类型转换。
  • 类类型的对象之间也可以隐式转换, 需要相应的构造函数支持。

1.1隐式类型转换的使用

#include<iostream>
using namespace std;
class A
{
public:
	A(int a1)
	{
		_a1 = a1;
	}
	void Print()
		{
		cout << _a1 << " " << _a2 << endl;
		}
	
private:
	int _a1;
	int _a2;
};
int main()
{
	A a1 = 1;//这里我们就用了隐式类型转换定义a1
	//平常我们定义是这样:A a1(1);
	return 0;
}

上面我们定义a1的时候,我们使用了隐式类型转换来定义,整形1其实先构造了一个A的临时对象,然后再用这个临时对象拷贝构造给a1。

在这个过程中,编译器会遇到连续构造+拷贝构造->优化为直接构造。

上面这个代码段是针对A(int a1)构造函数只有一个参数的情况下,如果有两个参数,我们想使用隐式类型转换,该如何操作呢?

如果我们按照错误示范1和2来操作的话,系统会报错。那么我们如何正确的操作呢?

这样写系统就不会报错啦

2.static成员

  • 用static修饰的成员变量,称之为静态成员变量,静态成员变量一定要在类外进行初始化。
  • 静态成员变量为所有类对象所共享,不属于某个具体的对象,不存在对象中,存放在静态区。
  • 用static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针。
  • 静态成员函数中可以访问其他的静态成员,但是不能访问非静态的,因为没有this指针。非静态的成员函数,可以访问任意的静态成员变量和静态成员函数。
  • 突破类域就可以访问静态成员,可以通过类名:静态成员 或者 对象.静态成员 来访问静态成员变量和静态成员函数。
  • 静态成员也是类的成员,受public、protected、private访问限定符的限制。
  • 静态成员变量不能在声明位置给缺省值初始化,因为缺省值是为了给构造函数初始化列表的,静态成员变量不属于某个对象,不走构造函数初始化列表。 

2.1 static 成员的使用

2.1.1static修辞成员变量
#include<iostream>
using namespace std;
class Rabit
{
public:
	Rabit(string color, string gender)
	{
		_color = color;
		_gender = gender;
		++_count;
	}
	Rabit(const Rabit& a)
	{
		_color = a._color;
		_gender = a._gender;
		++_count;
	}
private:
	//下面三个成员都是声明
	//兔子的颜色和性别需要使用字符串,因此这里是string类型
	static int  _count;//兔子的总数
	string  _color;//兔子的颜色
	string  _gender;//兔子的性别
};
int Rabit::_count = 0;//给兔子总数初始化,静态成员必须在类外进行定义和初实话,上面只是声明有这个成员,并没有定义
int main()
{
	Rabit a1("白色", "雄");
	Rabit a2("灰色","雌");
	return 0;
}

上面是我们定义了一个类Rabit。其中_gender 和 _color都是独属于实例化成员的成员变量。

比如你可以说:

兔子a1的颜色是白色,性别是雄性。兔子a2的颜色是灰色性别是雌性。

但是你不能说兔子a1的兔子总数_count是多少吧?

兔子总数_count是静态成员,它是独属于类Rabit的,不属于任何一个实例化对象。虽然它们能调用静态成员_count,却不能修改它,例如:

假设我们将private注释掉,这样我们就能在类外面使用我们的成员变量。由上面的图可以看到,我们的a1虽然想要修改_count但是却没有什么用,因为_static是属于整个类Rabit的,而不是独属于某一个实例化对象的。而且通过调试我们可以看出,实例化对象a1中招不到_count。更说明了静态成员_static是属于整个类Rabit的,而不是独属于某一个实例化对象的。

  • 同时静态成员_count并非只能通过实例化对象调用,通过使用   类名+::   同样可以调用。

  • 但是同样的,无法在类外面修改我们的静态成员_cout。静态成员_count只能在类里面修改,类外面是无法修改的。但是静态成员的初始化定义必须在类外面完成。

静态成员也是受类的成员,受public、protected、private访问限定符的限制。

  • 静态成员变量还是受访问限定符的限制的,就像上面,我们的_count被限定符private修辞了,在下面我们通过 类名+::的方式去访问类Rabit会发现找不到我们的成员变量(_count、_color、_gender)。
  • 同时静态成员既然受访问限定符的限制,那么肯定也会受到类域的限制(毕竟静态成员_count也是类的成员)

不使用  类名+::或者 实例化成对象.  的办法根本访问不到静态成员变量_count。

_count的生命周期虽然是全局的,但是会受到类域和访问限定符的限制。

  • 同时,静态成员变量不能在声明位置给缺省值初始化,因为缺省值是为了给构造函数初始化列表的,静态成员变量不属于某个对象,不走构造函数初始化列表。

如上图所示。初始化列表中不应该存在静态成员变量,既然静态成员变量不能存在初始化列表中,那么声明给初始值也肯定是错误的。会报以下错误:

2.1.2 static修辞成员函数

#include<iostream>
using namespace std;
class Rabit
{
public:
	Rabit(string color, string gender)
	{
		_color = color;
		_gender = gender;
		++_count;
	}
	Rabit(const Rabit& a)
	{
		_color = a._color;
		_gender = a._gender;
		++_count;
	}
	//获得兔子总数
	static int GetCount()//静态成员函数
	{
		_color = "无色";//这里是错误的用法
		return _count;
	}
//private:
	//下面三个成员都是声明
	//兔子的颜色和性别需要使用字符串,因此这里是string类型
	static int  _count;//兔子的总数
	string  _color;//兔子的颜色
	string  _gender;//兔子的性别
};
int Rabit::_count = 0;//给兔子总数初始化,静态成员必须在类外进行定义和初实话,上面只是声明有这个成员,并没有定义
int main()
{
	Rabit a1("白色", "雄");
	Rabit a2("灰色","雌");
	Rabit::_count=1000;
	//a1._count = 1000;
	return 0;
}

如上图中,我们在静态成员函数GetCount中出现了成员变量color是错误的行为,因为GetCount是静态成员函数,而color是非静态成员变量(C++规定:静态成员函数中可以访问其他的静态成员,但是不能访问非静态的,因为没有this指针。非静态的成员函数,可以访问任意的静态成员变量和静态成员函数

所以,这也是为什么GetCount访问_count没问题,而访问_color就会出错的原因。

三、结语

集帅集美们,今天的分享就到此结束了,咱们下次再见~

 

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

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

相关文章

# DBeaver 连接hive数仓

前提 前提是基于hadoop的hive服务已经启动&#xff0c;其中hive的服务包括metastore元数据服务和hiveserver2服务已经启动。hiveserver2服务在默认端口10000启动&#xff0c;且通过telnet xx.xx.xx.xx 10000 能通。 满足以上要求后&#xff0c;再可以看以下连接文档&#xff…

C++趣味编程玩转物联网:用树莓派Pico控制四位数码管

数码管是一种常用的数字显示器件&#xff0c;广泛应用于电子时钟、记分牌和智能设备显示界面。在本项目中&#xff0c;我们将通过树莓派Pico板控制一个四位数码管模块&#xff0c;展示从 0000 到 9999 的数字动态显示。这不仅是一次硬件和软件结合的实践&#xff0c;还可以帮助…

乌班图单机(不访问外网)部署docker和服务的方法

面向对象:Ubuntu不能访问外网的机子,部署mysql、redis、jdk8、minio 过程: 1、安装docker(照着图去这里找对应的下载下来https://download.docker.com/linux/static/stable/),将7个docker官网下载的文件下载下来后,传上去服务器随便一个文件夹或者常用的opt或者/usr/lo…

2024年11月27日Github流行趋势

项目名称&#xff1a;screenshot-to-code 项目维护者&#xff1a;abi clean99 sweep-ai kachbit vagusX项目介绍&#xff1a;通过上传截图将其转换为整洁的代码&#xff08;支持HTML/Tailwind/React/Vue&#xff09;。项目star数&#xff1a;62,429项目fork数&#xff1a;7,614…

K8s调度器扩展(scheduler)

1.K8S调度器 筛选插件扩展 为了熟悉 K8S调度器扩展步骤&#xff0c;目前只修改 筛选 插件 准备环境&#xff08;到GitHub直接下载压缩包&#xff0c;然后解压&#xff0c;解压要在Linux系统下完成&#xff09; 2. 编写调度器插件代码 在 Kubernetes 源代码目录下编写调度插件…

Qt桌面应用开发 第七天(绘图事件 绘图设备)

目录 1.绘图事件paintEvent 2.高级绘图 3.图片绘制 4.绘图设备 4.1QPixmap 4.2QBitmap 4.3QImage 4.4QPicture 1.绘图事件paintEvent paintEvent——绘图事件 需求&#xff1a;利用QPainter绘制点、线、圆、矩形、文字&#xff1b;设置画笔改为红色&#xff0c;宽度为…

Spring Boot 3 集成 Spring Security(3)数据管理

文章目录 准备工作新建项目引入MyBatis-Plus依赖创建表结构生成基础代码 逻辑实现application.yml配置SecurityConfig 配置自定义 UserDetailsService创建测试 启动测试 在前面的文章中我们介绍了 《Spring Boot 3 集成 Spring Security&#xff08;1&#xff09;认证》和 《…

ChatGPT的应用场景:开启无限可能的大门

ChatGPT的应用场景:开启无限可能的大门 随着人工智能技术的快速发展,自然语言处理领域迎来了前所未有的突破。其中,ChatGPT作为一款基于Transformer架构的语言模型,凭借其强大的语言理解和生成能力,在多个行业和场景中展现出了广泛的应用潜力。以下是ChatGPT八个最具代表…

13 —— 开发环境调错-source map

问题&#xff1a;代码被压缩后&#xff0c;无法正确定位源代码的位置&#xff08;行数和列数&#xff09; source map&#xff1a;准确追踪error和warning在原始代码的位置 —— webpack.config.js配置devtool选项 module.exports { devtool: inline-source-map }; inline-s…

水库大坝安全监测之量水堰计应用

量水堰计是水库大坝安全监测系统中的一种关键设备&#xff0c;主要用于测量水库水位、流量等水力参数。以下是量水堰计在水库大坝安全监测中的应用及注意事项&#xff1a; 一、量水堰计的工作原理 量水堰计是一种专门用于测量水流流量的仪器&#xff0c;其工作原理主要基于水流…

Scrapy图解工作流程-cnblog

1.1 介绍部分&#xff1a; 文字提到常用的Web框架有Django和Flask&#xff0c;接下来将学习一个全球范围内流行的爬虫框架Scrapy。 1.2 内容部分&#xff1a; Scrapy的概念、作用和工作流程 Scrapy的入门使用 Scrapy构造并发送请求 Scrapy模拟登陆 Scrapy管道的使用 Scrapy中…

复合查询和内外连接

文章目录 1. 简单查询2. 多表查询2.1 显示雇员名、雇员工资以及所在部门的名字2.2 显示部门号为10的部门名&#xff0c;员工名和工资2.3 显示各个员工的姓名&#xff0c;工资&#xff0c;及工资级别 3. 自连接4. 子查询4.1 where后的子查询4.1.1 单行子查询4.1.2 多行子查询 (i…

UniApp开发实战:常见报错解析与解决方案

UniApp开发实战&#xff1a;常见报错解析与解决方案 病例1、TypeError: undefined is not an object (evaluating ‘this. s c o p e . scope. scope.getAppWebview’) 需求&#xff1a;获取页面示例&#xff0c;动态修改头部搜索框内容&#xff0c;获取页面实例时候报错unde…

Docker 容器网络创建网桥链接

一、网络&#xff1a;默认情况下&#xff0c;所有的容器都以bridge方式链接到docker的一个虚拟网桥上&#xff1b; 注意&#xff1a;“172.17.0.0/16”中的“/16”表示子网掩码的长度为16位&#xff0c;它表示子网掩码中有16个连续的1&#xff0c;后面跟着16个连续的0。用于区分…

一个开源轻量级的服务器资源监控平台,支持告警推送

大家好&#xff0c;今天给大家分享一款开源的轻量级服务器资源监控工具Beszel&#xff0c;提供历史数据记录、Docker容器统计信息监控以及多种警报功能&#xff0c;用于监控服务器资源。 项目介绍 Beszel由hub&#xff08;中心服务器端应用&#xff0c;基于PocketBase构建&…

使用Compose Multiplatform开发跨平台的Android调试工具

背景 最近对CMP跨平台很感兴趣&#xff0c;为了练手&#xff0c;在移动端做了一个Android和IOS共享UI和逻辑代码的天气软件&#xff0c;简单适配了一下双端的深浅主题切换&#xff0c;网络状态监测&#xff0c;刷新调用振动器接口。 做了两年多车机Android开发&#xff0c;偶…

[MRCTF2020]Transform

查壳&#xff0c;拖入64位IDA LOBYTE8位就是一个字节&#xff0c;在此处无意义&#xff0c;因为我们输入的本来就是按字节输入的 设 a byte_414040,bdword_40F040,cbyte_40F0E0,输入的字符串为flag; 从题目里得到 加密代码 a[i] flag[b[i]]; a[i] ^ b[i]; c a 即c[i] a[i…

podman 源码 5.3.1编译

1. 构建环境 在麒麟V10服务器操作系统上构建&#xff1a;Kylin-Server-V10-GFB-Release-2204-Build03-ARM64.iso。由于只是编译 podman 源码&#xff0c;没必要特地在物理机或服务上安装一个这样的操作系统&#xff0c;故采用在虚拟机里验证。 2. 安装依赖 参考资料&#xf…

Llmcad: Fast and scalable on-device large language model inference

题目&#xff1a;Llmcad: Fast and scalable on-device large language model inference 发表于2023.09 链接&#xff1a;https://arxiv.org/pdf/2309.04255 声称是第一篇speculative decoding边缘设备的论文&#xff08;不一定是绝对的第一篇&#xff09;&#xff0c;不开源…

用Java爬虫“搜刮”工厂数据:一场数据的寻宝之旅

引言&#xff1a;数据的宝藏 在这个数字化的时代&#xff0c;数据就像是隐藏在数字丛林中的宝藏&#xff0c;等待着勇敢的探险家去发掘。而我们&#xff0c;就是那些手持Java魔杖的现代海盗&#xff0c;准备用我们的爬虫船去征服那些数据的海洋。今天&#xff0c;我们将一起踏…