类和对象2(难点)
类和对象2难点1.类的默认成员函数默认成员函数就是用户没有显式实现编译器会自动生成的成员函数称为默认成员函数对于一个类我们不写的情况下编译器会默认生成以下6个成员函数最重要的是前四个C11以后还会增加两个默认成员函数分别是移动构造和移动赋值6个默认成员函数 一初始化和清理 构造函数主要完成初始化工作 析构函数主要完成清理工作 二拷贝复制 拷贝构造是使用同类对象初始化创建对象 赋值重载主要是把一个对象赋值成另一个对象 三取地址重载 主要是普通对象和const对象取地址很少自己实现学习时要思考问题1.我们不写的时候编译器默认生成的函数行为是什么是否满足我们的需求2.编译器默认生成的函数不满足我们的要求需要自己实现如何自己实现2.构造函数构造函数是特殊的成员函数虽然叫构造但是构造函数的主要任务并不是开空间创造对象(我们常使用的局部对象是栈帧创建的时候空间就开好了)而是对象实例化时初始化对象构造函数的本质是替代我们以前Date类中写的Init函数的功能构造函数自动调用的特点就完美的替代了Init构造函数的特点1.函数名和类名相同2.无返回值返回值啥都不需要给也不需要写void3.对象实例化时系统会自动调用相应的构造函数4.构造函数可以重载5.如果类中没有显示定义构造函数则C编译器会自动生成一个无参的默认构造函数一旦用户显示定义编译器将不再生成6.无参构造函数、全缺省构造函数、我们不写构造时编译器默认生成的构造函数都叫做默认构造函数但是这三个函数有且只有一个存在不能同时存在。无参函数和全缺省函数虽然构成函数重载但是调用的时候会发生歧义其实就是不传参就可以调用的函数就叫做默认构造7.编译器默认生成的构造对内置类型成员变量的初始化没有要求也就是是否初始化是不确定的如果这个成员变量没有默认构造函数那么就会报错初始化成员变量需要用初始化列表才能解决补充C把类型分为内置类型基本类型和自定义类型内置类型就是语言提供的原生数据类型如int/指针等自定义类型就是使用class/struct等关键字自己定义的类型class Date { public: void Init(int year, int month, int day) { _year year; _month month; _day day; } Date() { //赋值构造 _year 1; _month 1; _day 1; } Date(int year, int month, int day) {//带参构造 _year year; _month month; _day day; } private: int _year; int _month; int _day; };对象实例化一定会调用构造函数确保实例化是正确的class Date { public: void Init(int year, int month, int day) { _year year; _month month; _day day; } Date(int year, int month, int day) {//带参构造 _year year; _month month; _day day; } private: int _year; int _month; int _day; }; int main() { Date d1; //这里会出现错误因为只有带参数的构造 //只有我们不进行自己构造的时候才默认构造不带参数的 }3.析构函数析构函数与构造函数功能相反析构函数不是完成对对象本身的销毁比如局部对象是存在栈帧的函数结束栈帧销毁他就释放了不需要我们管C 规定对象在销毁时会自动调用析构函数完成对对象中资源的清理释放工作。析构函数的功能类比我们之前 Stack 实现的 Destroy 功能而像 Date 没有 Destroy其实就是没有资源需要释放所以严格说 Date 是不需要析构函数的。析构函数的特点析构函数名是在类名前加上字符。无参数无返回值。(这里跟构造类似也不需要加 void)一个类只能有一个析构函数。若未显式定义系统会自动生成默认的析构函数。对象生命周期结束时系统会自动调用析构函数。跟构造函数类似我们不写编译器自动生成的析构函数对内置类型成员不做处理自定义类型成员会调用他的析构函数。还需要注意的是我们显式写析构函数对于自定义类型成员也会调用他的析构也就是说自定义类型成员无论什么情况都会自动调用析构函数。就拿手写栈来举例子手写栈的析构函数为~Stack() { free(a); _a nullptr; _capacity _top 0; }拷贝构造int main() { Date d1(2020, 2, 4);//普通构造 Date d2(d1);//拷贝构造 }如果一个构造函数的第一个参数是自身类类型的引用且任何额外的参数都有默认值则此构造函数也叫做拷贝构造函数也就是说拷贝构造是一个特殊的构造函数。拷贝构造的特点拷贝构造函数是构造函数的一个重载。普通构造用字面量 / 多参数创建全新空白对象拷贝构造用已存在的同类对象复制生成新对象 二者函数名都是类名参数列表不同构成重载编译器自动匹配调用。拷贝构造函数的第一个参数必须是类类型对象的引用使用传值方式编译器直接报错因为语法逻辑上会引发无穷递归调用。拷贝构造函数也可以多个参数但是第一个参数必须是类类型对象的引用后面的参数必须有缺省值。//Date d1(d2) Date(Date d) {//这里必须用引用不能用传值 _year d._year; _month d._month; _day d._day; } -------------------------- 假如使用了传值 Date(Date d) 调用该函数的时候值传递需要拷贝实参生成形参d 拷贝自定义对象必须调用拷贝构造函数第三条 于是再次执行Date(Date d)无限递归导致栈溢出编译器报错 ---------------------------------------- 多参拷贝构造规则 允许多个形参但是第一个必须是本类引用剩下的参数必须给默认值 否则不被认定为是拷贝构造 // 合法拷贝构造Date(const Date d, int addYear 0){} // 非法第二个参数无默认值不属于拷贝构造 Date(const Date d, int addYear){}C 规定自定义类型对象进行拷贝行为必须调用拷贝构造所以这里自定义类型传值传参和传值返回都会调用拷贝构造完成。若未显式定义拷贝构造编译器会生成自动生成拷贝构造函数。自动生成的拷贝构造对内置类型成员变量会完成值拷贝 / 浅拷贝 (一个字节一个字节的拷贝)对自定义类型成员变量会调用他的拷贝构造。显式定义析构函数并且释放资源一般是和自定义拷贝构造是绑定的传值返回会产生一个临时对象调用拷贝构造传值引用返回返回的是对象的别名没有产生拷贝。如果返回对象是一个当前函数局部域的局部对象函数结束就销毁了那么使用引用返回是有问题的这时的引用相当于一个类似于野指针的野引用传引用返回可以减少拷贝但是一定要确保返回对象在当前函数结束后还在才能引用返回补充浅拷贝和深拷贝的区别浅拷贝编译器默认拷贝构造的行为只复制对象内存表层的值对于普通内置变量int/double直接复制数值对于指针成员只复制指针本身的地址不会重新开辟堆内存。结果两个对象的指针指向同一块堆资源。深拷贝手动实现拷贝构造不仅复制表层变量当成员是堆指针时给新对象单独开辟一块全新堆内存将源对象堆里的数据完整复制到新堆空间 结果两个对象拥有独立的堆资源互不干扰。运算符重载1.当运算符被用于类类型的对象的时候C语言允许我们通过运算符重载的形式指定新的含义。C规定类类型对象使用运算符的时候必须转化成调用对应的运算符重载如果没有对应的运算符重载则会发生编译报错2.运算符重载是具有特殊名字的函数他的名字是operator和后面要定义的运算符共同构成和其他函数一样他也有返回类型和参数列表以及函数体3.重载运算符函数的参数个数和该运算符作用的运算对象数量一样多一元运算符有一个参数二元运算符有两个参数二元运算符的左侧运算对象传给第一个参数右侧传给第二个参数4.如果一个重载运算符函数是成员函数则他的第一个运算对象默认传给隐式的this指针因此运算符重载作为成员函数的时候参数比运算对象少一个5.运算符重载之后其优先级和结合性和对应的内置类型运算符保持一致还是以Date日期类举例子Date d1(2020, 2, 4);//普通构造 Date d3(2020, 2, 5); bool ret d3 d1;会产生报错错误原因二进制“”: 没有找到接受“Date”类型的左操作数的运算符(或没有可接受的转换)没有与这些操作数匹配的 “” 运算符这就用到了我们的运算符重载先用相等做例子bool operator(const Date d1,const Date d2){ return d1._yeard2._year d1._monthd2._month d1._day d2._day; }但是这里会发生报错原因是operator的参数过多说明是几元操作就是几个参数但是有一个隐含的this所以要发生改变this默认指向第一个参数bool operator(const Date d2) { if (this-_year d2._year) { return true; } else if (this-_month d2._month) { return true; } else if (this-_day d2._day) { return true; } else { return false; } }补充不能通过链接语法中没有的符号来创建新的操作符如operator.* :: sizeof ?: .以上五个运算符不能重载重载操作符至少要有一个类类型的参数不能通过运算符重载改变内置类型对象的含义一个类需要重载哪些运算符是看哪些运算符重载之后有意义比如Date类中的operator-有意义而没有意义重载运算符时有前置和后置运算符重载都是operator没办法很好的区分所以C规定后置重载的时候增加一个int实参和前置构成函数重载方便区分// 1. 前置d 无参数 Date operator(){ // 日期1简化逻辑只简单日1 _day;return *this; // 返回自增后的自身引用返回支持连续 } // 2. 后置d 多加一个int占位参数 Date operator(int){ Date temp *this; // 先保存原始值 _day; // 自身自增 return temp; // 返回修改前的旧对象值返回不能引用 }赋值运算符重载的特点1.赋值运算符重载是一个运算符重载规定必须重载为成员函数赋值运算符重载的参数建议写成 const 当前类类型引用否则传值传参会有拷贝2.有返回值且建议写成当前类型引用引用返回可以提高效率有返回值的目的是支持连续赋值操作d1 d2 d33.默认的赋值运算符重载也是浅拷贝//拷贝构造 Date d1(2002.2.2); Date d2(d1);//是创造一个新的 //赋值是存在的两个对象的拷贝 Date d3(2005.2.3); d1 d3; ///////////////////////////////////////////// Date operator (const Date d){ _year d._year; _monthd._month; _day d._day; return *this; }

相关新闻

Unity无相机HUD系统实现:基于UI Toolkit的常驻界面性能优化方案

Unity无相机HUD系统实现:基于UI Toolkit的常驻界面性能优化方案

1. 项目概述与核心思路最近在做一个Unity项目,需要实现一个全屏、常驻的HUD(抬头显示器)系统,比如显示全局的积分、倒计时、网络状态图标这类信息。最直接的想法可能就是用一个Canvas,设置Screen Space - Overlay&…

2026/7/19 1:12:13 阅读更多 →
技术解读:《智能体三角模型白皮书》中的三问校验法——意图共鸣科技的商用AI评估框架

技术解读:《智能体三角模型白皮书》中的三问校验法——意图共鸣科技的商用AI评估框架

你是一个企业的负责人。现在有一堆AI服务商来找你,都说"我们的AI很厉害,能帮您解决XX问题"。你怎么选?看参数?谁家模型更大、跑分更高?不靠谱。看案例?谁家服务了多少客户?不一定适合…

2026/7/19 1:11:13 阅读更多 →
Python必备模块指南:从数据处理到Web开发

Python必备模块指南:从数据处理到Web开发

1. Python常用模块概述作为一名Python开发者,我经常被问到:"Python有哪些必须掌握的模块?"这个问题看似简单,但背后涉及的是Python生态系统的核心能力。Python之所以能在数据科学、Web开发、自动化等领域占据主导地位&a…

2026/7/19 1:11:13 阅读更多 →

最新新闻

Python循环控制与优化技巧详解

Python循环控制与优化技巧详解

1. Python循环基础概念解析循环是编程中最基础也最重要的控制结构之一,它允许我们重复执行某段代码块,直到满足特定条件为止。在Python中,循环主要分为两种类型:for循环和while循环。1.1 for循环的基本语法Python的for循环与其他语…

2026/7/19 2:47:46 阅读更多 →
《辣知》——记录现实的勇气

《辣知》——记录现实的勇气

《辣知》——记录现实的勇气中国纪实文学的根与魂当虚构文学用想象拉开与现实的距离,纪实文学却反其道而行之——它用真实的笔触把读者拉近生活的本相,让人看见那些被宏大叙事遮蔽的细节,听见那些被时代噪音淹没的声音。2021年10月&#xff0…

2026/7/19 2:47:46 阅读更多 →
AI编排:企业级系统集成与大模型协同的中枢架构

AI编排:企业级系统集成与大模型协同的中枢架构

1. 项目概述:当企业级集成遇上大模型,为什么需要“AI编排”这个新角色我在做企业系统集成的第十个年头,第一次在客户现场听到“能不能让Salesforce自动告诉我哪个客户快流失了,再顺手写封挽留邮件”时,下意识摸了摸后颈…

2026/7/19 2:47:46 阅读更多 →
终极CNKI文献批量下载指南:如何用Python爬虫高效获取知网学术资源

终极CNKI文献批量下载指南:如何用Python爬虫高效获取知网学术资源

终极CNKI文献批量下载指南:如何用Python爬虫高效获取知网学术资源 【免费下载链接】CNKI-download :frog: 知网(CNKI)文献下载及文献速览爬虫 (Web Scraper for Extracting Data) 项目地址: https://gitcode.com/gh_mirrors/cn/CNKI-download 知网(CNKI)文献…

2026/7/19 2:47:46 阅读更多 →
Python编程入门:从零基础到开发实践

Python编程入门:从零基础到开发实践

1. 为什么选择Python作为编程入门语言作为一名从零开始学习编程的小白,选择Python作为第一门编程语言是个明智的决定。Python以其简洁优雅的语法著称,相比其他编程语言,它的代码更接近自然语言,降低了初学者的学习门槛。比如打印&…

2026/7/19 2:47:46 阅读更多 →
企业托管授权(Enterprise-Managed Authorization)

企业托管授权(Enterprise-Managed Authorization)

为什么需要它 在标准的 MCP 部署里,每个用户各自独立地授权某个 MCP 客户端访问某个 MCP 服务器。对消费级应用来说,这种"用户驱动"的模式很理想——个人掌握自己数据的访问权。 但放到企业环境里,这套模式会暴露出摩擦和安全缺口&…

2026/7/19 2:46:46 阅读更多 →

日新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/19 0:00:40 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/19 0:00:40 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/19 0:00:40 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/19 0:00:40 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/19 0:00:40 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/19 0:00:40 阅读更多 →

月新闻