当前位置: 首页 > article >正文

【学习笔记】C++(2)

C++学习笔记三、进阶 —— 类和对象1、概述2、基础 —— 公有、私有、保护、构造、析构3、拷贝构造、临时对象不能绑定到非const引用问题4、浅拷贝、深拷贝、移动拷贝5、静态6、内联和外联7、链表8、函数模板和类模板9、友元10、继承-派生(1) —— 基础11、继承-派生(2) —— 运算符重载12、继承-派生(3) —— 虚函数和多态13、继承-派生(4) —— 基类和派生类在内存中的布局14、继承-派生(5) —— 虚表和多态的内存布局三、进阶 —— 类和对象1、概述类是面向对象程序设计的基础和核心,也是实现数据抽象的工具。类中的数据具有隐藏性和封装性,类是实现C++许多高级特性的基础2、基础 —— 公有、私有、保护、构造、析构#includeiostream#includestringusingnamespacestd;classStudent{// 类的定义private:// 私有:只能类内访问intid;string secret;// 私有方法仅供内部使用voidprivateInfo(){coutname"'s id is "idendl;}protected:// 保护:类内和派生类可访问string major;public:// 公有:任意访问string name;intage;// 无参构造函数写法1//Student()//{// this-id = 0; this-name = "Unknow";this-age = 18; this-major = "Undecided";this-secret = "default";// cout "无参构造被调用" endl;//}// 无参构造函数写法2Student():id(0),name("Unknown"),age(18),major("Undecided"),secret("default"){cout"无参构造被调用"endl;}// 有参构造函数写法1//Student(int i, string n, int a, string m)//{// this-id = i; this-name = n; this-age = a;this-major = m; this-secret = "init_secret";// cout "有参构造被调用" endl;//}// 有参构造函数写法2Student(inti,string n,inta,string m):id(i),name(n),age(a),major(m),secret("init_secret"){cout"有参构造被调用"endl;}// 析构函数~Student(){cout"析构函数被调用"endl;}// getter/setter 访问私有属性intgetId(){returnid;}// gettervoidsetId(intnewId){id=newId;}// setterstringgetSecret(){returnsecret;}// gettervoidsetSecret(conststrings){secret=s;}// setter// 公有方法可供外部调用voidpublicInfo(){coutname"'s Age:"age" Major:"majorendl;}};intmain(){// 静态分配Student s1;// 无参构造s1.setId(1001);// setters1.name="s1";// 直接访问公有cout"s1's ID: "s1.getId()endl;// getters1.publicInfo();// 还可以用花括号创建实例Student s2={1002,"s2",21,"s222"};Student s3{1003,"s3",20,"s333"};Student arr1[2]={{1004,"s4",22,"s444"},{1005,"s5",21,"s555"}};// 动态分配Student*s6=newStudent(1004,"s6",23,"s666");// 有参构造s6-publicInfo();deletes6;Student*arr2=newStudent[2]{{},{}};return0;// 自动调用析构}TIP1、构造函数特点:必须是共有函数,不能有 return2、一个类默认含有:无参的构造函数、拷贝构造函数;其均可以重载,重载之后将覆盖默认自带的3、调用拷贝构造时,只触发拷贝构造,不会触发无参/有参构造4、重载了有参构造函数或拷贝构造函数后,也需要重载无参构造函数,否则类似于 Student s1; 会报错称类 Student 不存在默认的构造函数5、Student s3(Student()); 这一句可不是拷贝构造,这会被编译器理解为参数为一个返回Student的函数指针的返回值为Student类型的函数s3, 其等价于 Student s3(Student (*)());6、针对于上一点,C++11规定类似于 Student s3{Student()}; 这样的才是构造函数,区别在于将括号换成了花括号7、没标明是 public、private 还是 protect 的话,归为 private8、析构函数的特点:必须是共有函数,不能有 return,不能重载;栈空间下,相同定义域中后创建的先析构,不同定义域中定义域先结束的先析构;堆空间下,回收时立刻析构,不回收则不析构对象数组和对象指针#includeiostream#includestringusingnamespacestd;classStudent{private:string name;public:Student(){name="None";coutname" —— 无参构造"endl;}Student(string name):name(name){coutname" —— 有参构造"endl;}Student(constStudentstu){name=stu.name;coutname" —— 拷贝构造"endl;}~Student(){coutname" —— 析构"endl;}voidsetName(string name){this-name=name;}voiddisplay(){cout"My name is "nameendl;}};intmain(){// 静态分配// 法一// Student stu[3] = { {"A"},{"B"},{"C"} };// 法二:使用临时对象Student stu[3]={Student("A"),Student("B"),Student("C")};// 动态分配// 法一:分配内存时顺带初始化// Student* stu = new Student[3]{ {"A"},{"B"},{"C"} };// 法二// Student* stu = new Student[3];// for (int i = 0; i 3; i++)// {// stu[i].setName(to_string(i));// }// delete[] stu;// 法三// Student* stu = new Student[3];// for (int i = 0; i 3; i++)// {// (stu + i)-setName(to_string(i));// }// delete[] stu;// 法四// Student* stu = new Student[3];// Student* p = stu;// for (int i = 0; i 3; i++)// {// p-setName(to_string(i));// p++;// }// delete[] stu;return0;}TIP1、对于 Student stu[3] = { Student(“A”),Student(“B”),Student(“C”) }; 是不会触发临时对象到对象数组元素的拷贝构造,因为进行了返回值优化(RVO)—— 一种编译器优化技术,它让临时对象直接创建在对象数组元素所在的内存空间上,从而省去了拷贝构造,只会触发临时对象的有参构造函数2、对其规则:长度为n个字节的属性必须放置在n的整数倍的地址上;对象总的内存占用空间是其最长属性长度的整数倍一些正确写法#includeiostream#includestringusingnamespacestd;classStudent{private:string name;public:Student(){name="None";}Student(string name):name(name){}voiddisplay(){coutnameendl;}};intmain(){// 静态分配的写法Student s1;// 正确写法 触发无参构造// Student s2(); // 错误写法 这会被视为一个函数Students3_1("s3_1");// 正确写法 触发有参构造Student s3_2{"s3_2"};// 正确写法 触发有参构造Student s4={"s4"};// 正确写法 触发有参构造Student arr1[2]{{"s5"},{"s6"}};// 正确写法Student arr2[2]={{"s7"},{"s8"}};// 正确写法// 动态分配Student*s9_1=newStudent;// 正确写法,触发无参构造Student*s9_2=newStudent();// 正确写法,触发无参构造Student*s10=newStudent{};// 正确写法,触发无参构造Student*s11=newStudent("s11");// 正确写法,触发有参构造Student*s12=newStudent{"s12"};// 正确写法,触发有参构造Student*arr3=newStudent[2]{{},{"s13"}};// 正确写法return0;}TIP:静态分配且采用括号时不能触发无参构造,只能触发有参构造。如上不能 Student s2(); 但可以 Student s3_1( “s3_1” );3、拷贝构造、临时对象不能绑定到非const引用问题拷贝方式// 创建一个对象Student s1;// 使用已有的实例进行拷贝Students2(s1);Student s3=s1;Student s4{s1};// 使用临时对象进行拷贝Student s3=Student();Student s4=Student(s1);Student s4{Student()};TIP1、拷贝构造的参数必须加上,而const可加可不加(建议,但非必须)2、定义一个对象顺便让它等于一个同类对象,这触发的是拷贝构造,而不是赋值,因为定义的时候它还没被构造出来,需要先进行构造,而不能直接进行赋值;如果是 Student s; s=xxx; 那么这是先触发Student的无参构造再接上一个赋值语句必须加上 的原因:避免无限递归。根本原因在于如果不加上,则函数在执行时,会复制一份参数(不论是基本数据类型、指针,还是对象等)的副本,而这种复制会触发拷贝构造,进而陷入无限循环// 错误示例:没有Student(Student other){id=other.id;}Student s1;// 已有对象Students2(s1);// 调用拷贝构造函数// 陷入无限循环的过程// 第1步:调用 Student s2(s1),触发了s1的拷贝构造函数// ↓// 第2步:需要创建参数 other(值传递!)// ↓// 第3步:创建 other 需要拷贝 s1 → 调用s1拷贝构造函数// ↓// 第4步:再次需要创建参数 other(值传递!)// ↓// 第5步:创建 other 需要拷贝 s1 → 调用s1拷贝构造函数// ↓// 第6步:再次需要创建参数 other...// ↓// 无限循环:无限调用s1的拷贝构造函数!TIP:引用 的意思是 “直接使用原对象,不创建副本”建议加上 const 的原因:安全,防止引用的数据被修改// 不加const:允许但危险Student(Studentother){id=other.id;other.id=0;// 可以修改原对象!这不应该发生}// 加const:安全,推荐Student(constStudentother){id=other.id;// other.id = 0; // 编译错误!不能修改}建议加上 const 的原因还有:有助于提高编程的灵活性,因为 C++ 规定 ”临时对象不能绑定到非const引用“首先解释 ”临时对象” 和 “绑定到引用”:// Q:什么是临时对象// A:下面这些创建的都是临时对象(用完就扔)Student()// 默认构造临时对象Student(100)// 有参构造临时对象createStudent()// 函数返回的临时对象Student{}// C++11统一初始化临时对象// Q:什么是绑定到引用// A:实例s是普通对象,可以绑定到 Studentvoidfunc(Studentref)// ref绑定到传入的对象{ref.name="修改";}Student s;func(s);那么为什么临时对象不能绑定到非const引用?这并不是技术限制,而是 C++ 故意这么禁止的,因为认为参数不加 const 的话,那么有可能对临时对象进行修改,而随着函数的执行完成,被修改的临时对象也随即被销毁,这会让可能存在的修改临时对象的行为显得没有意义,因此故意这么禁止// 演示不给构造函数添加 const 时会引发的错误#includeiostream#includestringusingnamespacestd;classStudent{public:Student(){}Student(Studentother)// 没有const{cout"拷贝构造"endl;}};StudentcreateStudent(){Student s;returns;// 返回的是临时对象}intmain(){// 创建一个对象Student s1;// 情况1:明确创建临时对象Student s2=Student(s1);// 出错:临时对象不能绑定到非const引用// 情况2:显式调用构造函数Student s3=Student();// 出错:临时对象// 情况3:用{}初始化(C++11)Student s4{Student()};// 错误:临时对象// 情况4:函数返回(某些编译器设置下)autocreate=[]()-Student{Student s;returns;// 可能出错};Student s5=create();// 可能出错}TIP1、解决方法:只需为构造函数的参数加上 const 即可2、总结:临时对象可以传递给普通的形参例如参数是 Student other,但是如果形参是一个引用的话:Student other,那么为了临时对象能传递进去则必须给形参再加上一个 const 成为 const Student other写法是否允许建议原因Student(Student other)×禁止无限递归Student(Student other)√不建议不能绑定临时对象Student(const Student other)√推荐安全、灵活4、浅拷贝、深拷贝、移动拷贝浅拷贝:只复制指针,不复制指向的数据;多个对象共享同一块内存;危险在于一个对象删除内存会影响其他对象classShallowArray{private:int*data;intsize;public:// 默认拷贝构造(浅拷贝) —— 对于指针来说,只进行复制ShallowArray(){}ShallowArray(constShallowArrayother):data(other.data),size(other.size){cout"浅拷贝构造"endl;}};深拷贝:每个对象有独立的内存;优点在于安全,缺点在于性能开销大classDeepArray{private:int*data;intsize;public:// 深拷贝构造DeepArray(){}DeepArray(constDeepArrayother){size=other.size;data=newint[size];// 申请新内存for(inti=0;isize;i++){data[i]=other.data[i];// 复制数据}cout"深拷贝构造"endl;}~DeepArray(){delete[]data;// 安全,不冲突}};移动拷贝:原对象变为"空壳";优点在于高性能,适合临时对象classMoveArray{private:int*data;intsize;

相关文章:

【学习笔记】C++(2)

C++学习笔记 三、进阶 —— 类和对象 1、概述 2、基础 —— 公有、私有、保护、构造、析构 3、拷贝构造、临时对象不能绑定到非const引用问题 4、浅拷贝、深拷贝、移动拷贝 5、静态 6、内联和外联 7、链表 8、函数模板和类模板 9、友元 10、继承-派生(1) —— 基础 11、继承-…...

系统辨识避坑指南:为什么你的脉冲响应总不准?从相关分析法到参数优化

系统辨识避坑指南:为什么你的脉冲响应总不准?从相关分析法到参数优化 系统辨识是控制工程中的一项基础技术,而脉冲响应作为系统动态特性的直接反映,其准确性直接影响后续控制器设计。但在实际工程中,许多开发者常遇到脉…...

Win11新机Office2021兑换失败?解决老账号Office2016冲突的完整指南

1. 为什么新电脑无法兑换Office2021? 刚拿到Win11新机的小伙伴们,经常会遇到一个让人头疼的问题:明明新电脑预装了Office2021,打开Word却发现显示"Office2016已激活"。这种情况我遇到过不下十次,每次帮朋友处…...

智慧教育——解读AI一体化智慧校园解决方案【附全文阅读】

适应人群为学校管理人员、教师、学生、技术运维人员及教育信息化建设相关从业者。主要内容围绕 AI 一体化智慧校园建设,阐述总体规划及革命性意义(提升教学管理水平、降低成本等);介绍八大应用中心(教学管理、物联网管控、校园安全等),涵盖智能选课排课、校园安防监控等…...

【高等数学】第一讲:函数与初等函数

目录 函数的基本概念 函数的表示法 函数的几种重要特性 有界性 例子 区间的有界性 仅单侧有界的函数 单调性 全定义域上严格单调的函数 分区间单调的函数 奇偶性 偶函数 奇函数 分段函数奇偶性 分段奇函数 分段偶函数 周期性 初等函数 常数函数 幂函数…...

咨询进阶——详解《商业模式思维的30个技巧》

《商业模式思维的30个技巧》读书笔记可提炼关键技巧:如用价值链连接客户价值、深入理解客户细分与价值定位、灵活调整商业模式、制定差异化定价策略、履行社会责任、持续创新及重视人才管理等[3][18]。 详答 一、核心技巧提炼 客户价值与价值链连接 构建价值传递机制:通过价…...

跨境电商为什么必须布局 SEO?

在跨境电商领域,获取流量的方式通常包括: 广告投放平台流量社交媒体推广SEO 自然流量 其中,SEO 往往被很多卖家忽视,但实际上,它是跨境电商最稳定、最具长期价值的流量来源之一。 那么问题来了: 为什么…...

题目1514:蓝桥杯算法提高VIP-夺宝奇兵

#include<iostream> using namespace std; int dp[110][110]; int main(){ int n; cin>>n; for(int i1;i<n;i){ for(int j1;j<i;j){ cin>>dp[i][j]; } } //从倒数第二行向上推 for(int in-1;i&g…...

ADXL345嵌入式驱动开发:I²C/SPI寄存器配置与FreeRTOS中断集成

1. ADXL345加速度传感器库深度解析&#xff1a;面向嵌入式工程师的底层驱动开发指南ADXL345是Analog Devices公司推出的超低功耗、高分辨率&#xff08;13位&#xff09;、数字输出三轴加速度传感器&#xff0c;广泛应用于姿态检测、振动监测、跌倒报警、工业预测性维护及可穿戴…...

重新安装微信新版本后才发现历史记录文件夹名称不匹配!解决方法

重新 安装/恢复 电脑&#xff0c;安装微信最新版本 记录文件夹变更为&#xff1a;xwechat_files 旧的格式&#xff1a;WeChat Files 找很多方法&#xff0c;以及腾讯官方的说明&#xff0c;无效、费解&#xff0c;来点干货&#xff0c;成功解决经验&#xff1a; &#xff08;1&…...

OpenClaw+千问3.5-9B:自动化社交媒体内容发布

OpenClaw千问3.5-9B&#xff1a;自动化社交媒体内容发布 1. 为什么需要自动化内容发布工具 作为一个同时运营多个社交媒体平台的技术博主&#xff0c;我每天要花大量时间在不同平台间切换&#xff1a;先在Markdown写好文章&#xff0c;然后手动复制到微信公众号后台排版&…...

课堂学习1

Miniconda 安装教程 (2026版) Anaconda 是最流行的 Python 和 R 语言数据科学平台&#xff0c;它包含了康达包管理器&#xff08;Conda&#xff09;、Python 以及 1500 个科学包及其依赖项。&#xfeff;Miniconda 可以看作是 Anaconda 的“轻装版”&#xff0c;只自带 conda …...

【VBA】【EXCEL】【文件】读写已打开EXCEL

Sub readExcel()Set wb Workbooks("数据源.xlsx") Set ws wb.Sheets(1)For i 2 To 100For j 2 To 1000If ws.Range("B" & j).Value <> "" ThenIf InStr(me.Range("A" & i).Value, ws.Range("B" & j).…...

seo网上教程有哪些常见错误

SEO网上教程有哪些常见错误 在互联网时代&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;已经成为网站流量和排名提升的关键因素。很多人在学习SEO过程中&#xff0c;常常会遇到一些误区&#xff0c;甚至在网上找到的一些教程中也包含了不少错误。本文将详细介绍一些常见…...

嵌入式工程师职业发展:原厂与方案商技术深度对比

1. 嵌入式工程师的职业抉择&#xff1a;原厂与方案商深度对比最近一位工作三年的嵌入式工程师朋友分享了他的求职经历&#xff0c;让我感触颇深。他在方案商做了三年应用开发后&#xff0c;最终选择跳槽到芯片原厂。这个决定背后&#xff0c;反映了很多嵌入式工程师都会面临的职…...

三相光伏逆变器研发深度解析:全源代码解读与性能优化指南

三相10Kw光伏并网逆变器。包含全套理图/PCB/源代码一、概述 本文档详细解读基于TI F28379D DSP芯片的三相10kW光伏并网逆变器代码系统。该代码采用模块化设计&#xff0c;涵盖核心控制、硬件抽象、参数配置、驱动适配等多个功能层级&#xff0c;支持交流开环、电流环独立逆变、…...

OpenClaw自动化写作对比:千问3.5-35B-A3B-FP8与纯文本模型的产出差异

OpenClaw自动化写作对比&#xff1a;千问3.5-35B-A3B-FP8与纯文本模型的产出差异 1. 为什么需要对比不同模型的写作表现 上周我在用OpenClaw自动生成技术文档时&#xff0c;发现一个有趣的现象&#xff1a;同样的任务指令&#xff0c;交给不同的大模型处理&#xff0c;产出的…...

电动汽车模型考虑多种需求响应及微网的虚拟电厂日前优化调度模型的MATLAB代码(含空调负荷)

MATLAB代码&#xff1a;含多种需求响应及电动汽车的微网/虚拟电厂日前优化调度 关键词&#xff1a;需求响应 空调负荷 电动汽车 微网优化调度 虚拟电厂调度 仿真平台&#xff1a;MATLABCPLEX 主要内容&#xff1a;代码主要做的是一个微网/虚拟电厂的日前优化调度模型&#…...

全栈开发者工具链:OpenClaw+Qwen3.5-9B-AWQ-4bit辅助前端调试

全栈开发者工具链&#xff1a;OpenClawQwen3.5-9B-AWQ-4bit辅助前端调试 1. 为什么需要AI辅助前端调试 作为全栈开发者&#xff0c;我经常陷入这样的困境&#xff1a;当页面渲染出现异常时&#xff0c;需要在控制台日志、网络请求和DOM树之间反复切换排查。传统调试流程至少包…...

别再只调RGB了!用HSV给你的WS2812灯带调出更自然的彩虹渐变(附Arduino代码)

别再只调RGB了&#xff01;用HSV给你的WS2812灯带调出更自然的彩虹渐变&#xff08;附Arduino代码&#xff09; 每次看到WS2812灯带突然跳变的颜色&#xff0c;总觉得少了点优雅。RGB数值的直接操控就像用扳手调钢琴——理论上可行&#xff0c;但实际操作起来总差那么点意思。上…...

2025_NIPS_JavisGPT: A Unified Multi-modal LLM for Sounding-Video Comprehension and Generation

JavisGPT 论文核心总结与翻译 一、主要内容总结 JavisGPT 是首个面向同步音视频(sounding video)理解与生成的统一多模态大语言模型(MLLM),核心解决现有模型将音视频视为独立模态、缺乏时空同步建模的问题。 模型采用编码器-LLM-解码器架构,以 Qwen2.5-VL-7B-Instruct…...

Geekble测谎模块Arduino库:GSR生理信号采集与多模态反馈

1. 项目概述Geekble_LieDetector 是一款面向嵌入式平台&#xff08;典型为基于ATmega328P的Arduino兼容控制器&#xff09;设计的生理信号检测与交互控制库&#xff0c;专用于驱动 Geekble LieDetector 模块。该模块并非传统意义上的“测谎仪”&#xff0c;而是一个以皮肤电导&…...

姜翰奇补题

3.23-3.29一、PTA天梯赛5:第5&#xff0c;7&#xff0c;8&#xff0c;10&#xff0c;11&#xff0c;12二、牛客&#xff1a;136周赛三、马蹄集&#xff1a;DFS和BFS搜索题目四、牛客&#xff1a;蓝桥杯模拟赛3.30-4.5一、PTA天梯赛6:第8、9、10二、牛客&#xff1a;137周赛三、…...

东莞市SEO优化对网站收录有何影响_东莞市SEO优化的常见问题有哪些

东莞市SEO优化对网站收录有何影响 在互联网时代&#xff0c;东莞市的企业和个人网站希望在搜索引擎上获得高排名&#xff0c;是非常重要的目标。搜索引擎优化&#xff08;SEO&#xff09;在这一过程中扮演了关键角色。东莞市SEO优化对网站收录有何影响呢&#xff1f;SEO优化不…...

30分钟搭建个人AI助手:OpenClaw+千问3.5-35B-A3B-FP8极速体验

30分钟搭建个人AI助手&#xff1a;OpenClaw千问3.5-35B-A3B-FP8极速体验 1. 为什么选择这个组合&#xff1f; 上周六下午&#xff0c;我盯着电脑里散落的会议纪要、待办事项和未整理的截图发愁时&#xff0c;突然意识到&#xff1a;与其手动处理这些琐事&#xff0c;不如让AI…...

Python高效处理字符串去重的5种实用技巧

1. 字符串去重的核心逻辑与应用场景 字符串去重是数据处理中最基础却高频的操作之一。想象你手里有一串钥匙&#xff0c;其中几把是重复的&#xff0c;去重就是帮你挑出唯一的那几把。在Python中处理用户输入、日志清洗或数据预处理时&#xff0c;我经常遇到需要去除重复字符的…...

高效制作IO通道测试表:从位号表到VLOOKUP函数实战

1. 为什么需要IO通道测试表&#xff1f; 在工业自动化项目中&#xff0c;IO通道测试表是FAT&#xff08;工厂验收测试&#xff09;环节的必备工具。想象一下你正在调试一个化工厂的DCS系统&#xff0c;面对成百上千个温度、压力、流量信号&#xff0c;如果没有一个清晰的测试清…...

作品被篡改署名?三步维权指南

您好&#xff0c;我理解您遇到了作品被他人擅自修改并署名为“悟空”的情况&#xff0c;这确实是一件令人非常气愤和不快的事情。首先&#xff0c;请务必保持冷静。愤怒是正常的&#xff0c;但清晰的行动才能更好地维护您的权益。针对这种情况&#xff0c;您可以按照以下步骤来…...

一篇顶一万篇,很难找到代码这么全的高分文章,WGS、RNA-seq、scRNA-seq、免疫肽组质谱联合分析

&#x1f680;科研不掉发&#xff0c;快来这个地表最强的生信神仙网站&#xff1a;中国银河生信云平台&#x1f449; 立即访问&#xff1a;https://usegalaxy.cn结直肠癌免疫治疗中&#xff0c;多数新抗原筛选仅聚焦编码区&#xff0c;大量潜在靶点被忽略&#xff0c;非编码区能…...

Java程序设计(第3版)第二章——变量的三种定义方式2和3

变量的第二种使用方式 在声明的同时并赋值 数据类型 变量名 &#xff1d; 数据; int b &#xff1d; 12; System.out.println(b); 输出为12变量的第三种使用方式 同时定义多个同类型变量 int c,d&#xff1d;1,e&#xff1d;11,f&#xff1d;23,g&#xff1d;32,h&#xff1d;0…...