类和对象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/11/2 15:14:50 阅读更多 →
技术解读:《智能体三角模型白皮书》中的三问校验法——意图共鸣科技的商用AI评估框架

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

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

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

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

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

2026/11/9 18:22:46 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/12 5:00:00 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/12 5:13:20 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/12 5:13:20 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/12 18:22:26 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/12 18:22:25 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/12 5:13:20 阅读更多 →

日新闻

周新闻

月新闻