类和对象(四)
在 C 的面向对象编程中构造函数是每个类都绕不开的核心话题。它负责在对象创建时完成初始化是对象生命周期中第一个被调用的成员函数。本文将继续深入探讨构造函数的进阶用法——初始化列表并进一步讲解类型转换与static 成员这两个与对象创建、访问密切相关的知识点。通过本文的学习你将理解为什么某些成员变量必须放在初始化列表中初始化以及如何利用构造函数实现类型之间的转换、如何借助 static 成员实现跨对象的共享数据。构造函数续之前我们所讲的构造函数是用于在实例化对象时对这个对象进行初始化。我们可以显式地定义构造函数不定义时编译器也会自动生成。这里我们再深入讲解构造函数中最重要的部分初始化列表。关于我们之前Date类构造函数的写法是这样的classDate{public:Date(intyear1,intmonth1,intday1){_yearyear;_monthmonth;_dayday;}private:int_year;int_month;int_day;};如果我们写成初始化列表那么这个构造函数应该是这样的Date(intyear1,intmonth1,intday1)//初始化列表的格式:_year(year)//将year的值赋给_year,_month(month)//同理,_day(day){;}初始化列表的写法是一个冒号后跟成员变量括号内部是表达式或变量用于初始化前面的成员变量后面的成员变量初始化都跟在逗号后面。而且在初始化列表中每个成员只能出现一次。函数体内部可以什么都不写我们一般建议将初始化都写到初始化列表当中因为所有的成员变量都要进入初始化列表。成员变量进入初始化列表的顺序与成员变量声明的顺序完全一致这里先进入初始化列表的是_year然后是_month最后是_day。C11 规定我们可以给成员变量设定一个缺省值比如这里我们给_year设定默认值为 2026然后不在初始化列表里面初始化_year。classDate{public:Date(intyear1,intmonth1,intday1):_month(month),_day(day){;}private:int_year2026;//设定缺省值而非赋值int_month;int_day;};对于这样一个构造函数是如何进入初始化列表的呢这里_year先进入初始化列表但是初始化列表没有显式写_year的初始化所以编译器会去找_year的缺省值将它的缺省值赋给_year。后面的成员变量在初始化列表中都显式地写了会用我们设定的值正常初始化。像这样的成员变量我们可以把它的初始化写在初始化列表也可以写在函数体内但有三种变量我们必须写在初始化列表中。引用、const 修饰的变量、没有默认构造函数的类我们都必须在初始化列表中进行初始化。这三类变量存在一个共同点那就是必须在创建时就进行初始化且只能初始化这一次。classTime{public:Time(inthours,intminutes):_hours(hours),_minutes(minutes){;}private:int_hours;int_minutes;};classDate{public:Date(intyear1,intmonth1,intday1):_month(month),_day(day)//必须写在初始化列表中,_i(day),_a(1),_t(4,5){;}private:int_year2026;//设定缺省值而非赋值int_month;int_day;int_i;constint_a;Time _t;};这三类对象必须进入初始化列表的原因都很好理解。关于成员变量进入初始化列表初始化的逻辑我们可以用以下这张图来概括这也就是初始化列表的所有内容了那么在构造函数的函数体内我们可以干什么呢我们可以完成初始化列表做不到的事。比如我们用 malloc 函数申请一块空间的时候都要判断一下是否申请成功这个判断我们就可以放到函数体内完成因为初始化列表做不到。classStack{public:Stack(intn4):_a((int*)malloc(n*sizeof(int))),_top(0),_capacity(n){//判断是否申请成功if(_aNULL){perror(malloc);exit(-1);}}private:int*_a;int_top;int_capacity;};类型转换我们来看一个类classA{public:A(inta1):_a1(a){;}voidPrint(){cout_a1endl;}private:int_a1;};然后我们用2去构造一个类对象能成功吗intmain(){A a12;a1.Print();return0;}结果发现成功了为什么呢这是因为发生了类型转换。在 C 语言中我们知道它支持内置类型转换比如整型和浮点型、指针和整型等等但不支持自定义类型的转换。在 C 中是支持的我们可以把内置类型转换为自定义类型同时也支持自定义类型和自定义类型之间进行转换但需要通过构造函数来实现。内置类型转换为自定义类型这里A a1 2就发生了类型转换2先传过去构造了一个临时对象该临时对象再拷贝构造a1对于这种连续的构造拷贝构造会被编译器优化为直接构造。我们知道临时对象具有常性在之前的 const 引用中我们也知道发生了类型转换的表达式必须使用 const 引用所以我们想给它取别名应该这样写constAa22;不使用 const 修饰就会出现权限放大的问题编译也不通过。这是传一个参数的构造函数那么对于要传两个参数以及更多参数的构造函数呢我们应该如何用内置类型去直接构造classA{public:A(inta11,inta21):_a1(a1),_a2(a2){;}voidPrint(){cout_a1 _a2endl;}private:int_a1;int_a2;};如果我们直接用括号括起来写成A a (1,2)就相当于逗号表达式了实际传过去的参数就变成了一个所以要用大括号括起来A a1{1,2};a1.Print();也可以写成这样Aa1({1,2});自定义类型之间的转换对于自定义类型之间的转换则需要通过相应的构造函数来实现。classA{friendclassB;public:A(inta11,inta21):_a1(a1),_a2(a2){;}voidPrint(){cout_a1 _a2endl;}private:int_a1;int_a2;};classB{public:B(Aa):_b1(a._a1),_b2(a._a2){;}private:int_b1;int_b2;};intmain(){Aa1({1,2});B b1a1;//类A去构造Breturn0;}static成员我们知道每个类对象中都有自己的成员变量它们都是相互独立的那么存在 static 成员会是什么情况这里我们想统计类 C 对象的创建次数但又不想外部可以直接修改那么定义成全局变量显然不合理考虑到类的封装性我们把它定义成 static 成员变量。//统计类C的创建次数classC{public:C(){_ret;}C(constCc){_ret;}private://定义成静态成员变量staticint_ret;};因为_ret属于整个类是所有对象共有的所以它不会进入初始化列表我们需要在类外面初始化它且只能初始化一次需要指定类域来查找。intC::_ret0;//初始化成0然后我们给外部提供一个接口使外部可访问_ret的值从而拿到类对象的创建次数。staticintGet_ret(){return_ret;}因为要访问的成员被static修饰了所以我们也用 static 成员函数来访问该成员它与普通成员函数的区别在于内部不含有 this 指针并且只能访问 static 成员普通成员函数静态和非静态成员变量都可访问。intmain(){C c1;Cc2(c1);C c3;coutc3.Get_ret()endl;return0;}

相关新闻

遥感光伏图像 遥感无人机光伏分割数据集 利用mask形式准确分割标注出光伏面板的位置

遥感光伏图像 遥感无人机光伏分割数据集 利用mask形式准确分割标注出光伏面板的位置

大规模遥感无人机光伏分割数据集 超过11万张各类遥感光伏图像,利用mask形式准确分割标注出光伏面板的位置。数据集共20GB大规模光伏分割数据集项目详情数据集名称大规模光伏分割数据集图像总量11万张遥感光伏图像数据大小20GB标注类型Mask掩码分割标注,精…

2026/9/30 7:22:17 阅读更多 →
预算紧张时怎么起步?SaaS 与源码的入门门槛对比

预算紧张时怎么起步?SaaS 与源码的入门门槛对比

刚起步的商家,现金流往往是头等大事。SaaS 手机号注册即自动分配商城空间,不用买服务器、不用请技术,几百块就能把店开起来,试错成本很低,跑不通损失也有限。 源码部署看似入门零成本。但真正跑起来,要付服…

2026/9/30 7:21:17 阅读更多 →
一文教会昇腾ATC模型转换工具:把开源模型编译成NPU能跑的格式

一文教会昇腾ATC模型转换工具:把开源模型编译成NPU能跑的格式

昇腾 ATC 模型转换入门指南:把训练模型变成 NPU 能跑的 OM 一句话让Agent变成昇腾专家,昇腾任务轻松搞定。评测入口:请按这个开源仓接入昇腾图谱 https://gitcode.com/agent0/kg-tools 你花几天训练出一个深度学习模型,满怀期待地…

2026/9/30 7:21:17 阅读更多 →

最新新闻

Linux软硬链接本质:inode与路径的底层原理

Linux软硬链接本质:inode与路径的底层原理

1. 为什么软硬链接不是“复制”,而是“指针”——从文件系统底层讲清楚你有没有试过用ln命令创建一个链接,结果发现删掉源文件后,软链接打不开、硬链接还能访问?或者反过来,改了软链接指向的文件,硬链接却毫…

2026/9/30 7:56:32 阅读更多 →
Linux软链接与硬链接的本质区别及实战应用

Linux软链接与硬链接的本质区别及实战应用

1. 为什么软链接和硬链接不是“差不多就行”的替代品?在Linux系统里,软链接(symbolic link)和硬链接(hard link)常被新手统称为“快捷方式”,但这种类比会埋下严重隐患。我刚入行时就吃过亏&…

2026/9/30 7:56:32 阅读更多 →
SAP S/4HANA部署方式选择实战决策指南

SAP S/4HANA部署方式选择实战决策指南

简介:本资源是一份面向SAP系统实施顾问、云架构师及企业数字化转型从业者的S/4HANA云部署方式深度解析文档,聚焦SAP官方当前主流的四种部署模型及其业务定位差异,有效解决企业在上云路径选择中的决策困惑。文档以清晰对比方式展开&#xff1a…

2026/9/30 7:56:32 阅读更多 →
uni-app 登录页 UI 精修:从背景层到页面栈的细节实战

uni-app 登录页 UI 精修:从背景层到页面栈的细节实战

uni-app 里给微信小程序做登录页面,第一版基本都停留在“能用”的阶段:一个 logo、两个输入框、一个按钮,收工。等产品拿着竞品截图走过来,说一句“这个登录页面 UI 好看,你照着改一下”,很多人才发现自己在…

2026/9/30 7:56:32 阅读更多 →
uni-app微信小程序登录页:Vue3纯CSS高转化UI实战

uni-app微信小程序登录页:Vue3纯CSS高转化UI实战

做小程序登录页这件事,我前后推倒重来过至少七个版本。第一版是照着教程堆出来的深色背景配白色输入框,自认为挺"高级",结果上线一周后后台数据显示登录页跳出率接近四成;第二版换了配色,数据没动&#xff1…

2026/9/30 7:56:32 阅读更多 →
拆开这个环:优化 RAG 通道,解开 SEO 与 GEO 的死循环

拆开这个环:优化 RAG 通道,解开 SEO 与 GEO 的死循环

摘要:GEO 没有标准,它只是 RAG 的引用打分回路。这个回路正在反向磨平人类内容:RLHF 把 AI 磨成平均值,GEO 再让人类照着这个平均值生长,两个平均化首尾相接,咬成死循环。解法不是拒绝 AI,也不是…

2026/9/30 7:55:32 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 8:16:59 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 16:41:41 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/29 8:24:48 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/29 3:55:56 阅读更多 →