通用企业网站织梦模板(红绿蓝三色)网站自动化开发

张小明 2026/1/10 10:18:38
通用企业网站织梦模板(红绿蓝三色),网站自动化开发,网站开发设备费用计入什么科目,天津有哪些好的做网站公司#x1f525;承渊政道#xff1a;个人主页 ❄️个人专栏: 《C语言基础语法知识》 《数据结构与算法初阶》《C初阶知识内容》 ✨逆境不吐心中苦,顺境不忘来时路! #x1f3ac; 博主简介: 引言:前篇小编介绍了关于C类和对象(中)的内容,本篇将继续介绍C类和对象(下)的内容,至此…承渊政道个人主页❄️个人专栏:《C语言基础语法知识》 《数据结构与算法初阶》《C初阶知识内容》✨逆境不吐心中苦,顺境不忘来时路! 博主简介:引言:前篇小编介绍了关于C类和对象(中)的内容,本篇将继续介绍C类和对象(下)的内容,至此类和对象的学习就告一段落了!哪还有什么需要学习的?废话不多说,带着这些疑问,下面跟着小编的节奏一起学习吧目录1. 深入了解构造函数2.类型转换3.static成员4.友元5.内部类6.匿名对象7.对象拷⻉时的编译器优化1. 深入了解构造函数之前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅式,就是初始化列表,初始化列表的使⽤⽅式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成员列表,每个成员变量后⾯跟⼀个放在括号中的初始值或表达式.1️⃣每个成员变量在初始化列表中只能出现⼀次,语法理解上初始化列表可以认为是每个成员变量定义初始化的地⽅.2️⃣引⽤成员变量,const成员变量,没有默认构造的类类型变量,必须放在初始化列表位置进⾏初始化,否则会编译报错.3️⃣C11⽀持在成员变量声明的位置给缺省值,这个缺省值主要是给没有显⽰在初始化列表初始化的 成员使⽤的.4️⃣尽量使⽤初始化列表初始化,因为那些你不在初始化列表初始化的成员也会⾛初始化列表,如果这个成员在声明位置给了缺省值,初始化列表会⽤这个缺省值初始化.如果你没有给缺省值,对于没有显⽰在初始化列表初始化的内置类型成员是否初始化取决于编译器,C并没有规定.对于没有显示在初始化列表初始化的⾃定义类型成员会调⽤这个成员类型的默认构造函数,如果没有默认构造会编译错误.5️⃣初始化列表中按照成员变量在类中声明顺序进⾏初始化,跟成员在初始化列表出现的的先后顺序⽆关.建议声明顺序和初始化列表顺序保持⼀致.初始化列表总结⽆论是否显示写初始化列表,每个构造函数都有初始化列表;⽆论是否在初始化列表显示初始化成员变量,每个成员变量都要⾛初始化列表初始化并按照声明顺序走;#includeiostreamusingnamespacestd;classTime{public:Time(inthour):_hour(hour){coutTime()endl;}private:int_hour;};classDate{public:Date(intx,intyear1,intmonth1,intday1):_year(year),_month(month),_day(day),_t(12),_ref(x),_n(1){// error C2512: “Time”: 没有合适的默认构造函数可⽤// error C2530 : “Date::_ref” : 必须初始化引⽤// error C2789 : “Date::_n” : 必须初始化常量限定类型的对象}voidPrint()const{cout_year-_month-_dayendl;}private:int_year;int_month;int_day;Time _t;// 没有默认构造int_ref;// 引⽤constint_n;// const};intmain(){inti0;Dated1(i);d1.Print();return0;}#includeiostreamusingnamespacestd;classTime{public:Time(inthour):_hour(hour){coutTime()endl;}private:int_hour;};classDate{public:Date():_month(2),_day(1){coutDate()endl;}voidPrint()const{cout_year-_month-_dayendl;}private:// 注意这⾥不是初始化这⾥给的是缺省值这个缺省值是给初始化列表的// 如果初始化列表没有显⽰初始化默认就会⽤这个缺省值初始化int_year1;int_month1;int_day;Time _t1;constint_n1;int*_ptr(int*)malloc(12);};intmain(){Date d1;d1.Print();return0;}//思考一下这个程序输出什么?#includeiostreamusingnamespacestd;classA{public:A(inta):_a1(a),_a2(_a1){}voidPrint(){cout_a1 _a2endl;}private:int_a22;int_a12;};intmain(){Aaa(1);aa.Print();}输出结果为:1 随机值(_a2 的具体值无固定规律)核心分析:1️⃣成员初始化顺序:由声明顺序决定,而非初始化列表书写顺序类A中私有成员的声明顺序是:int _a2 2; → int _a1 2;,因此构造函数初始化列表的执行顺序是:先初始化 _a2再初始化 _a1哪怕初始化列表写的是 _a1(a), _a2(_a1).2️⃣初始化列表优先级 类内初始值C11支持类内给成员赋初始值(如 _a22、_a12),但如果成员在初始化列表中被显式初始化,类内初始值会被覆盖.本程序中 _a2 和 _a1 都在初始化列表中指定了初始化方式.因此类内的2完全不生效.3️⃣未初始化成员的取值:随机值初始化 _a2 时,初始化列表要求 _a2(_a1),但此时 _a1 还未被初始化(声明顺序在后,后初始化),_a1 是未定义的垃圾值(内置类型 int 未初始化时,值为随机数),因此 _a2 被赋值为随机值,后续初始化 _a1 时,_a1(a) 中 a1,因此 _a1 被正确初始化为1.//若想让 _a2 也初始化为 1有两种方式//方式 1调整成员声明顺序让 _a1 先声明classA{public:A(inta):_a1(a),_a2(_a1){}voidPrint(){cout_a1 _a2endl;}private:int_a12;// 先声明 _a1int_a22;// 后声明 _a2};// 此时输出1 1//方式 2直接用参数a初始化_a2classA{public:A(inta):_a1(a),_a2(a)// 直接用a初始化,不依赖_a1{}voidPrint(){cout_a1 _a2endl;}private:int_a22;int_a12;};// 此时输出1 12.类型转换1️⃣C⽀持内置类型隐式类型转换为类类型对象,需要有相关内置类型为参数的构造函数.2️⃣构造函数前⾯加explicit就不再⽀持隐式类型转换.3️⃣类类型的对象之间也可以隐式转换,需要相应的构造函数⽀持.#includeiostreamusingnamespacestd;classA{public:// 构造函数explicit就不再⽀持隐式类型转换// explicit A(int a1)A(inta1):_a1(a1){}//explicit A(int a1, int a2)A(inta1,inta2):_a1(a1),_a2(a2){}voidPrint(){cout_a1 _a2endl;}intGet()const{return_a1_a2;}private:int_a11;int_a22;};classB{public:B(constAa):_b(a.Get()){}private:int_b0;};intmain(){// 1构造⼀个A的临时对象再⽤这个临时对象拷⻉构造aa3// 编译器遇到连续构造拷⻉构造-优化为直接构造A aa11;aa1.Print();constAaa21;// C11之后才⽀持多参数转化A aa3{2,2};// aa3隐式类型转换为b对象// 原理跟上⾯类似B baa3;constBrbaa3;return0;}//优化的情况需要在Linux系统环境下去运行观察3.static成员1️⃣⽤static修饰的成员变量,称之为静态成员变量,静态成员变量⼀定要在类外进⾏初始化.2️⃣静态成员变量为所有类对象所共享,不属于某个具体的对象,不存在对象中,存放在静态区.3️⃣⽤static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针.4️⃣静态成员函数中可以访问其他的静态成员,但是不能访问⾮静态的,因为没有this指针.5️⃣⾮静态的成员函数,可以访问任意的静态成员变量和静态成员函数.6️⃣突破类域就可以访问静态成员,可以通过类名::静态成员或者对象.静态成员来访问静态成员变量和静态成员函数.7️⃣静态成员也是类的成员,受public、protected、private 访问限定符的限制.8️⃣静态成员变量不能在声明位置给缺省值初始化,因为缺省值是个构造函数初始化列表的,静态成员变量不属于某个对象,不⾛构造函数初始化列表.// 实现⼀个类,计算程序中创建出了多少个类对象#includeiostreamusingnamespacestd;classA{public:A(){_scount;}A(constAt){_scount;}~A(){--_scount;}staticintGetACount(){return_scount;}private://类⾥⾯声明staticint_scount;};//类外⾯初始化intA::_scount0;intmain(){coutA::GetACount()endl;A a1,a2;Aa3(a1);coutA::GetACount()endl;couta1.GetACount()endl;// 编译报错error C2248: “A::_scount”: ⽆法访问 private 成员(在“A”类中声明)//cout A::_scount endl;return0;}//输出:0 3 3核心分析思路:该程序的核心目标是统计程序运行过程中类A的对象创建总数,核心依赖C中static成员变量 / 成员函数的特性,结合构造函数、拷贝构造函数、析构函数的调用时机实现计数.一、核心原理:static成员变量的特性(计数的基础)1️⃣共享性:static成员变量_scount属于类A本身(而非某个具体对象),存储在静态/全局数据区,所有A类对象共享这一个变量,因此能作为 “全局计数器” 统计所有对象的创建/销毁.2️⃣初始化规则:static成员变量需类内声明,类外初始化(int A::_scount 0;)若仅类内声明不初始化,会触发链接错误;初始值设为0,因为计数从 0 开始.3️⃣访问权限:_scount被声明为private,类外无法直接访问(如cout A::_scount报错),需通过public的static成员函数作为接口访问.二、计数逻辑:构造/拷贝构造1、析构-1对象的 “创建” 和 “销毁” 对应计数器的增减,核心依赖构造/析构函数的调用时机:下面表格直观解析关键:只要是 “新对象被创建”,无论通过普通构造还是拷贝构造,都要计数1;析构仅在对象销毁时-1(不影响main中 “创建后未销毁” 的计数结果).三、访问接口:static成员函数GetACount()特性:static成员函数属于类,无this指针,可通过类名调用(A::GetACount())或对象调用(a1.GetACount()),两种方式等价(因为不依赖具体对象). 作用:封装对private成员_scount的访问,提供安全的计数读取接口.拓展:若需统计 “当前存活的对象数”当前程序的_scount实际统计的是当前存活的对象数(创建1,销毁-1);若需统计 “程序运行中创建过的总对象数(含已销毁)”,只需移除析构函数中的–_scount,让计数器只增不减即可.函数类型调用场景计数操作作用无参构造函数直接创建新对象(如Aa1, a2)_scount新对象创建,计数1拷贝构造函数用已有对象拷贝创建新对象(如A a3(a1))_scount拷贝对象创建,计数1析构函数对象生命周期结束(如main结束时局部对象销毁)_scount--对象销毁,计数-1求123…n_classSum{public:Sum(){_ret_i;_i;}staticintGetRet(){return_ret;}private:staticint_i;staticint_ret;};intSum::_i1;intSum::_ret0;classSolution{public:intSum_Solution(intn){// 变⻓数组Sum arr[n];returnSum::GetRet();}};4.友元1️⃣友元提供了⼀种突破类访问限定符封装的⽅式,友元分为:友元函数和友元类,在函数声明或者类声明的前⾯加friend,并且把友元声明放到⼀个类的⾥⾯.2️⃣外部友元函数可访问类的私有和保护成员,友元函数仅仅是⼀种声明,他不是类的成员函数.3️⃣友元函数可以在类定义的任何地⽅声明,不受类访问限定符限制.4️⃣⼀个函数可以是多个类的友元函数.5️⃣友元类中的成员函数都可以是另⼀个类的友元函数,都可以访问另⼀个类中的私有和保护成员.6️⃣友元类的关系是单向的,不具有交换性,⽐如A类是B类的友元,但是B类不是A类的友元.7️⃣友元类关系不能传递,如果A是B的友元,B是C的友元,但是A不是C的友元.8️⃣有时提供了便利.但是友元会增加耦合度,破坏了封装,所以友元不宜多⽤.#includeiostreamusingnamespacestd;// 前置声明,则A的友元函数声明编译器不认识BclassB;classA{// 友元声明friendvoidfunc(constAaa,constBbb);private:int_a11;int_a22;};classB{// 友元声明friendvoidfunc(constAaa,constBbb);private:int_b13;int_b24;};voidfunc(constAaa,constBbb){coutaa._a1endl;coutbb._b1endl;}intmain(){A aa;B bb;func(aa,bb);return0;}#includeiostreamusingnamespacestd;classA{// 友元声明friendclassB;private:int_a11;int_a22;};classB{public:voidfunc1(constAaa){coutaa._a1endl;cout_b1endl;}voidfunc2(constAaa){coutaa._a2endl;cout_b2endl;}private:int_b13;int_b24;};intmain(){A aa;B bb;bb.func1(aa);bb.func1(aa);return0;}5.内部类1️⃣如果⼀个类定义在另⼀个类的内部,这个内部类就叫做内部类.内部类是⼀个独⽴的类,跟定义在全局相⽐,他只是受外部类类域限制和访问限定符限制,所以外部类定义的对象中不包含内部类.2️⃣内部类默认是外部类的友元类.3️⃣内部类本质也是⼀种封装,当A类跟B类紧密关联,A类实现出来主要就是给B类使⽤,那么可以考虑把A类设计为B的内部类,如果放到private/protected位置,那么A类就是B类的专属内部类,其他地⽅都⽤不了.#includeiostreamusingnamespacestd;classA{private:staticint_k;int_h1;public:classB// B默认就是A的友元{public:voidfoo(constAa){cout_kendl;//OKcouta._hendl;//OK}int_b1;};};intA::_k1;intmain(){coutsizeof(A)endl;A::B b;A aa;b.foo(aa);return0;}//我们再来看看如果使用内部类怎么去解决 求123...n_?classSolution{// 内部类classSum{public:Sum(){_ret_i;_i;}};staticint_i;staticint_ret;public:intSum_Solution(intn){// 变⻓数组Sum arr[n];return_ret;}};intSolution::_i1;intSolution::_ret0;6.匿名对象1️⃣⽤类型(实参)定义出来的对象叫做匿名对象,相⽐之前我们定义的类型对象名(实参)定义出来的叫有名对象.2️⃣匿名对象⽣命周期只在当前⼀⾏,⼀般临时定义⼀个对象当前⽤⼀下即可,就可以定义匿名对象.classA{public:A(inta0):_a(a){coutA(int a)endl;}~A(){cout~A()endl;}private:int_a;};classSolution{public:intSum_Solution(intn){//...returnn;}};intmain(){A aa1;// 不能这么定义对象因为编译器⽆法识别下⾯是⼀个函数声明,还是对象定义//A aa1();// 但是我们可以这么定义匿名对象,匿名对象的特点不⽤取名字// 但是他的⽣命周期只有这⼀⾏,我们可以看到下⼀⾏他就会⾃动调⽤析构函数A();A(1);Aaa2(2);// 匿名对象在这样场景下就很好⽤,当然还有⼀些其他使⽤场景,以后遇到了再说Solution().Sum_Solution(10);return0;}7.对象拷⻉时的编译器优化1️⃣现代编译器会为了尽可能提⾼程序的效率,在不影响正确性的情况下会尽可能减少⼀些传参和传返回值的过程中可以省略的拷⻉.2️⃣如何优化C标准并没有严格规定,各个编译器会根据情况⾃⾏处理.当前主流的相对新⼀点的编译器对于连续⼀个表达式步骤中的连续拷⻉会进⾏合并优化,有些更新更激进的编译器还会进⾏跨⾏跨表达式的合并优化.3️⃣linux下可以将下⾯代码拷⻉到test.cpp⽂件,编译时⽤ g test.cpp -fno-elideconstructors的⽅式关闭构造相关的优化.#includeiostreamusingnamespacestd;classA{public:A(inta0):_a1(a){coutA(int a)endl;}A(constAaa):_a1(aa._a1){coutA(const A aa)endl;}Aoperator(constAaa){coutA operator(const A aa)endl;if(this!aa){_a1aa._a1;}return*this;}~A(){cout~A()endl;}private:int_a11;};voidf1(A aa){}Af2(){A aa;returnaa;}intmain(){// 传值传参// 构造拷⻉构造A aa1;f1(aa1);coutendl;// 隐式类型连续构造拷⻉构造-优化为直接构造f1(1);// ⼀个表达式中连续构造拷⻉构造-优化为⼀个构造f1(A(2));coutendl;cout***********************************************endl;// 传值返回// 不优化的情况下传值返回编译器会⽣成⼀个拷⻉返回对象的临时对象作为函数调⽤表达式的返回值// ⽆优化 vs2019 debug// ⼀些编译器会优化得更厉害将构造的局部对象和拷⻉构造的临时对象优化为直接构造(vs2022 debugf2();coutendl;// 返回时⼀个表达式中连续拷⻉构造拷⻉构造-优化⼀个拷⻉构造 vs2019 debug// ⼀些编译器会优化得更厉害进⾏跨⾏合并优化将构造的局部对象aa和拷⻉的临时对象和接收返回值对象aa2优化为⼀个直接构造。vs2022 debugA aa2f2();coutendl;// ⼀个表达式中开始构造中间拷⻉构造赋值重载-⽆法优化vs2019 debug// ⼀些编译器会优化得更厉害进⾏跨⾏合并优化将构造的局部对象aa和拷⻉临时对象合并为⼀个直接构造vs2022 debugaa1f2();coutendl;return0;}敬请期待下一篇文章内容–通过做题深入理解和复习类和对象的相关知识!
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

用wordpress开发网站模板下载策划案模板范文

宽论作为一种科学、系统的交易理念,其量化交易的三大工具 —— 弹论、CDVA 分型以及带鱼短鱼理论,在市场实战中相互配合、协同作战,为投资者构建了一个强大的交易体系。深入探究这三大工具的协同机制,对投资者提升交易水平具有重要…

张小明 2026/1/9 14:11:44 网站建设

免费观看电视剧网站赚钱软件一天赚100元游戏

LaMa图像修复模型性能优化实战:从PyTorch到TensorRT的完整加速方案 【免费下载链接】lama 项目地址: https://gitcode.com/gh_mirrors/lam/lama 还在为LaMa图像修复模型的推理速度而烦恼吗?🤔 每次处理高分辨率图像都要等待好几分钟&…

张小明 2026/1/9 14:31:49 网站建设

上传到网站空间商务网站的建设与维护

你是否经常被任务栏上那个不断弹出的安全中心图标所困扰?即使已经安装了第三方安全软件,Windows安全中心依然固执地提醒你"安全防护已关闭",打扰你的工作专注度。本文将为你提供从简单到彻底的三种解决方案,让你完全掌控…

张小明 2026/1/9 23:00:38 网站建设

四川做网站公司宁波网络建站模板

PyTorch Lightning 如何重塑高效模型训练 在深度学习项目中,你是否经历过这样的场景:好不容易设计好一个新模型,信心满满地准备训练,结果一运行就报错 CUDA out of memory?或者想尝试多卡并行,却被复杂的分…

张小明 2026/1/9 21:50:32 网站建设

dw做的网站有域名么网站建设个人主页图

LangFlow区块链存证试点应用 在司法科技与人工智能加速融合的今天,一个现实问题日益凸显:AI生成的内容如何被信任?尤其是在合同审查、知识产权确权等高敏感场景中,即便模型输出再精准,若缺乏可验证的过程记录和防篡改的…

张小明 2026/1/10 6:36:00 网站建设

宝山顺德网站建设邵阳做网站价格

个人博客 目录 基于springboot vue个人博客系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取: 基于springboot vue个人博客系统 一、前言 博主介绍:✌️大…

张小明 2026/1/9 16:37:27 网站建设