还剩48页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
语言课件(精简版)C++欢迎参加C++语言精简版课程!本课程由资深编程专家主讲,旨在帮助学员快速掌握C++核心知识与实践技能无论您是高校学生、自学编程爱好者还是备战考研的学子,这套精简课件都将为您提供清晰、系统的C++学习路径语言简介C++起源与创始人语言特点C++语言诞生于1983年,由丹麦C++完全兼容C语言,同时支持计算机科学家Bjarne面向对象编程范式它既保留了Stroustrup在贝尔实验室开发C语言的高效性和底层操作能Stroustrup博士设计C++的初衷力,又增加了抽象、封装、继承是为C语言增加面向对象的特和多态等面向对象的核心特性性,最初被称为带类的CCwith Classes应用领域发展简史C++1C++98/031998年,C++首个国际标准正式发布(ISO/IEC14882:1998),奠定了C++的基础规范2003年进行了小幅修订,主要修复了标准中的缺陷,这两个版本被合称为C++98/032C++11/142011年发布的C++11是一次重大革新,引入了自动类型推导、lambda表达式、右值引用、智能指针等现代特性C++14在此基础上进行了增强,提高了语言的易用性3C++17/20/23C++17引入了结构化绑定、if/switch变量声明等便捷特性C++20带来了协程、概念、模块等革命性变化最新的C++23继续推进语言简化与现代化,增强了标准库功能与语言区别C++C面向对象特性扩展功能兼容性C++支持类与对象的概念,通过封装、继C++提供泛型编程(模板)、异常处理、C++保持与C语言的高度兼容性,几乎所承和多态实现面向对象编程而C语言是命名空间等C语言所不具备的现代语言特有合法的C程序都是合法的C++程序然纯粹的面向过程语言,缺乏直接的对象性这些特性使得代码更加模块化、安而,良好的C++编程风格通常不同于C语抽象机制全且可复用言的传统做法•类和对象的概念•模板与泛型编程•继承与多态•异常处理机制•访问控制•STL标准库编程环境C++命令行编译流程编译器选择基本的命令行编译过程编写源代码.cpp文件→选择合适的IDE主流C++编译器包括GCC/G++(开源、跨平使用编译器编译(如g++main.cpp-oC++开发常用的集成开发环境IDE包括台)、Microsoft VisualC++(Windows平台)、program)→运行生成的可执行文件掌握这一Microsoft Visual Studio(Windows平台最强大Clang(LLVM项目的前端,兼容性好)不同编流程有助于理解C++程序的构建过程的IDE)、Code::Blocks(跨平台且轻量)、译器对C++标准的支持程度可能略有差异CLion(JetBrains出品的现代C++IDE)以及VSCode(配合扩展可支持C++开发)第一个程序示例C++源代码结构必要组件完整代码示例第一个C++程序通常是经典的Hello,使用#include iostream引入输入输int main{std::coutHello,World!它由头文件包含、主函数定出流库,这是C++标准库的一部分,提world!;return0;}义和输出语句组成这个简单的程序展供了基本的输入输出功能每个C++程这段代码使用std::cout输出流显示文本,示了C++程序的基本框架结构序都需要一个main函数作为程序的入口并通过return0表示程序正常结束函点数的大括号{}定义了函数体的范围基本语法结构C++注释方式语句结尾C++支持两种注释风格单行注释使用在C++中,每个语句必须以分号(;)结双斜杠(//),注释内容从//开始到行束,这是语句的终结符缺少分号是初尾;多行注释使用/**/包围,可以跨越学者最常见的语法错误之一多行主函数入口代码块每个C++程序必须包含一个main函数,C++使用花括号{}来定义代码块,用于它是程序执行的起点main函数的标准组织语句函数体、循环体、条件分支返回类型是int,表示程序结束状态等都需要用花括号包围数据类型分类衍生类型包括数组、指针、引用和函数类型用户自定义类型类class、结构体struct、枚举enum和联合union基本数据类型整型int、浮点型float/double、字符型char、布尔型boolC++的类型系统是其强大功能的基础基本数据类型提供了存储和操作不同种类数据的能力整型用于表示整数值,浮点型用于表示实数,字符型用于单个字符,布尔型则用于逻辑值(真/假)用户自定义类型允许程序员创建满足特定需求的复杂数据结构其中,类是C++面向对象编程的核心,提供数据封装和行为定义的机制结构体类似于类但默认成员为公有,枚举定义命名常量集合,联合则提供在同一内存位置存储不同类型数据的能力变量与常量声明变量声明与初始化C++中变量声明的基本语法是数据类型变量名[=初始值];例如int count=10;声明了一个名为count的整型变量并初始化为10变量声明时最好同时进行初始化,避免使用未初始化的变量常量定义使用const关键字定义常量,表示该值在程序执行期间不可修改例如const doublePI=
3.14159265359;定义了一个名为PI的常量常量必须在声明时进行初始化,且之后不能被修改左值与右值左值lvalue代表内存位置,可以出现在赋值运算符左侧;右值rvalue代表临时值,只能出现在赋值运算符右侧理解左值与右值的概念对于深入理解C++的值语义和引用语义非常重要常量与枚举常量const枚举类型enumC++中使用const关键字定义常量,一旦初始化就不能修改常枚举是一种用户自定义类型,用于表示一组具名的整型常量传量在编译时就确定其值,可以提高程序的可读性和安全性统枚举(C风格)示例const intMAX_STUDENTS=100;enum Color{RED,GREEN,BLUE};//RED=0,GREEN=1,BLUE=2C++11引入了constexpr关键字,用于定义编译期常量表达式,C++11引入强类型枚举,提供更好的类型安全性可以在编译时计算值,提高运行效率enum classSeason{SPRING,SUMMER,AUTUMN,WINTER};示例constexpr doublePI=
3.14159265359;使用强类型枚举时,必须通过枚举类型名访问Season::SPRING输入与输出标准输出cout标准输入cin格式控制std::cout是C++标准库提供std::cin是标准输入流对象,C++提供了多种格式化输出的输出流对象,用于向控制用于从控制台读取用户输入的方法,包括操纵符台输出数据使用插入运算使用提取运算符从输入manipulator如符将数据发送到输出流流获取数据std::endl换行、std::setw设置宽度等示例std::cinage;示例std::cout当前温需要包含iomanip头文件度是temperature使用高级格式化功能度std::endl;C++的输入输出系统基于流stream的概念,将数据视为连续的字节流标准库提供了丰富的流类和操作,使得数据的输入输出操作变得简单灵活除了控制台输入输出外,C++还支持文件流fstream和字符串流stringstream,可以方便地进行文件操作和字符串解析运算符与表达式类别运算符示例算术运算符+,-,*,/,%,++,--a+b,a*b,a%b关系运算符==,!=,,,=,=a==b,a!=b逻辑运算符,||,!ab,!flag位运算符,|,^,~,,ab,a2赋值运算符=,+=,-=,*=,/=,%=a=b,a+=5C++表达式由运算符和操作数组成,根据运算符优先级和结合性确定计算顺序优先级从高到低大致为括号、一元运算符、算术运算符、关系运算符、逻辑运算符、赋值运算符当有疑问时,建议使用括号明确表示运算顺序C++支持多种复合赋值运算符+=,-=等,它们提供了简化代码的方式,如a+=b等价于a=a+b,但通常更加高效自增++和自减--运算符有前缀和后缀两种形式,区别在于返回值前缀形式返回变量的新值,后缀形式返回变量的旧值控制结构C++分支结构if-else,switch-case用于条件判断和多路分支循环结构for,while,do-while实现重复执行特定代码块跳转语句break,continue,return控制程序流程C++的控制结构提供了灵活管理程序流程的能力分支结构允许程序根据条件执行不同的代码路径if语句适用于简单条件判断,switch语句则适合多条件分支场景,特别是当条件基于单个变量或表达式的不同值循环结构使得重复执行代码变得简单for循环通常用于已知迭代次数的情况,while循环适用于基于条件的不确定次数循环,do-while循环确保至少执行一次循环体选择合适的循环结构可以使代码更加清晰高效if语句用法举例单分支结构最基本的if语句只有一个条件分支,当条件为真时执行相应代码块if score=60{std::cout及格;}双分支结构if-else语句在条件为真时执行if代码块,否则执行else代码块if age=18{std::cout成年人;}else{std::cout未成年人;}多分支结构使用if-else if-else可以处理多种条件if score=90{grade=A;}else ifscore=80{grade=B;}else ifscore=70{grade=C;}else{grade=D;}C++还提供了三元运算符:作为if-else语句的简洁替代,特别适用于简单条件赋值max=aba:b;//如果a大于b,则max=a,否则max=b循环结构详解for循环while循环for循环适合已知迭代次数的场景,语法while循环在条件为真时重复执行代码块,结构为for初始化;条件;更新{循环适合未知迭代次数的场景体}while条件{循环体}示例forint i=0;i10;i++{sum+=示例whilecinvaluei;}{processvalue;}C++11引入了基于范围的for循环forauto elem:container{}do-while循环do-while循环至少执行一次循环体,然后再检查条件do{循环体}while条件;示例do{password=getPassword;}while!isValidpassword;循环控制语句break和continue提供了额外的流程控制能力break用于立即退出循环,通常用于找到目标后提前结束搜索;continue用于跳过当前迭代中的剩余代码,立即进入下一次迭代数组基础数组定义与初始化多维数组数组注意事项C++数组是存储相同类型元C++支持多维数组,最常见数组索引从0开始,范围是素的顺序集合,定义语法的是二维数组,类似于矩[0,size-1]为类型数组名[大小];阵C++不会自动检查数组越示例int numbers
[5]=int matrix
[3]
[4]={{1,2,3,界,越界访问可能导致未定{1,2,3,4,5};4},{5,6,7,8},{9,10,11,义行为12}};可以省略大小让编译器自动数组名实际上是指向第一个计算int scores[]={95,访问元素matrix
[1]
[2]表元素的指针常量88,72};示第2行第3列的元素(值为7)传统C++数组存在一些局限性大小固定,不能在运行时改变;不知道自身大小,需要单独记录;函数间传递时退化为指针因此,现代C++更推荐使用std::array(固定大小)和std::vector(动态大小)来替代原始数组,它们提供了更安全、更灵活的接口字符串基础C风格字符串C++string类C风格字符串是以空字符\0结尾的字符数组C++标准库提供的string类,需要包含string头文件char name
[10]=张三;//自动添加结束符\0std::string message=你好,世界!;优点是内存占用小,与C语言兼容性好string类支持丰富的操作,如缺点是容易出现缓冲区溢出,操作不便•长度获取message.length•子串提取message.substr0,2需要使用cstring中的函数如strlen,strcpy,strcmp等处理•查找message.find世界•连接message+欢迎学习C++在现代C++中,强烈推荐使用std::string而非C风格字符串,因为string类能自动管理内存,防止缓冲区溢出,并提供丰富的成员函数string类还支持国际化字符集,虽然对于中文等非ASCII字符,需要注意编码问题(如UTF-
8、GB2312等)指针基础概念指针定义与基本操作指针是存储内存地址的变量,通过星号*声明int*p;//p是指向整数的指针取地址运算符获取变量地址p=a;//p指向变量a解引用运算符*访问指针指向的值*p=10;//通过p修改a的值指针和数组数组名是指向第一个元素的指针常量int arr
[5];int*p=arr;//p指向arr
[0]指针算术p+1指向arr
[1],*p+i等价于arr[i]通过指针遍历数组forint*p=arr;parr+5;p++{...}指针的高级应用动态内存分配int*p=new int;//分配单个整数动态数组int*arr=new int
[10];//分配10个整数的数组内存释放delete p;delete[]arr;//防止内存泄漏空指针nullptr(C++11)或NULL表示不指向任何对象的指针指针是C++中最强大但也最容易出错的特性之一常见错误包括空指针解引用、悬挂指针(指向已释放的内存)、内存泄漏(忘记释放动态分配的内存)等现代C++引入了智能指针(如std::unique_ptr、std::shared_ptr)来自动管理内存,减少这些错误引用类型引用定义与特性引用与指针的区别引用是变量的别名,使用符号定义int ref=引用必须初始化,不能为空;指针可以为空或在声var;明后修改引用必须在声明时初始化,且不能更改为引用其他引用使用时无需解引用;指针需要使用*操作符变量引用提供了更安全、更直观的间接访问机制引用没有自己的内存地址,直接操作被引用的对象引用作为函数参数引用参数实现按引用传递,函数内的修改会影响原始值const引用用于大型对象参数传递,既高效又安全函数可以返回引用,但须确保引用对象的生命周期引用在C++中有广泛应用,特别是在函数参数和返回值中按引用传递参数可以避免大对象的复制开销,提高性能例如,传递大型容器或复杂对象时,使用引用比值传递更有效率void processVectorconststd::vectorint vec;引用还适用于运算符重载,使得自定义类型能够像内置类型一样使用操作符当函数返回引用时(尤其是类成员函数),通常用于支持链式调用,如obj.method
1.method2;函数基础函数定义C++函数的基本定义格式是返回类型函数名参数列表{函数体}示例int addint a,int b{return a+b;}函数声明(原型)通常放在头文件中,实现放在源文件参数传递方式值传递参数是原始值的副本,函数内修改不影响外部引用传递参数是原始值的别名,函数内修改会影响外部指针传递传递变量地址,通过解引用修改原始值函数重载C++允许同一作用域中定义多个同名但参数列表不同的函数编译器根据参数类型和数量决定调用哪个版本返回类型不同但参数相同的函数不构成重载函数是C++程序的基本构建块,允许将代码组织为可复用的逻辑单元良好的函数设计应遵循单一职责原则,即一个函数只做一件事情函数应有清晰的命名、适当的注释和错误处理机制对于大型对象参数,推荐使用const引用传递以避免不必要的复制void processconststd::string text如果函数不需要修改参数且参数是基本类型,则使用值传递;如果需要修改参数,使用非const引用或指针函数参数默认值默认参数定义调用带默认参数的函数C++允许函数参数指定默认值,当调用时可以省略有默认值的参数display5;未提供该参数则使用默认值//等价于display5,0,0void displayint a,int b=0,int c=0;也可以覆盖默认值display5,10;//等价于display5,10,0默认参数必须从右向左指定,不能只为左边参数提供默认值而右边不提供必须按顺序提供参数,不能跳过中间参数默认参数声明规则默认参数通常在函数声明(头文件)中指定,不在定义中重复如果函数在定义前被调用,必须先有带默认参数的声明默认参数可以是常量、全局变量或函数调用函数参数默认值提供了灵活的函数接口设计方式,特别适用于具有常用值的参数例如,设计一个绘图函数时可以为颜色、线宽等参数提供常用默认值,使常见用例调用更简洁void drawLineintx1,int y1,int x2,int y2,Color color=BLACK,int thickness=1;内联函数与函数模板内联函数inline函数模板template内联函数是一种优化技术,用于减少函数调用的开销函数调用通常涉及函数模板是C++泛型编程的基础,允许创建可处理不同数据类型的函数,压栈、跳转和返回等操作,而内联函数在编译时会将函数体直接插入到调而无需为每种类型编写重复代码用点,省去了这些开销定义方式使用template关键字和类型参数定义方式使用inline关键字template typenameTinline intmaxint a,int b{return aba:b;}T maxT a,T b{return aba:b;}内联是对编译器的建议而非命令,编译器可能忽略内联请求(如对于太大调用时,编译器根据实参类型实例化具体函数max10,20;max
3.14,或含有循环的函数)
2.71;模板参数可以有多个,也可以有默认类型和非类型参数(如整数常量)内联函数主要用于简单且频繁调用的小函数,可以显著提高性能现代编译器通常会自动进行内联优化,即使没有explicit inline声明类定义内部实现的成员函数也隐式地被视为内联候选变量作用域和生命周期局部变量全局变量在函数或块内部声明的变量,作用域限于声明它在函数外部声明的变量,作用域延伸到声明点之的块内局部变量在进入块时创建,退出块时销后的整个文件全局变量在程序启动时创建,程毁,存储在栈上例如void func{int x=序结束时销毁,存储在静态数据区多文件共享10;}//x只在func内可见全局变量需要使用extern关键字静态变量自动类型推导使用static关键字声明的变量静态局部变量保C++11引入的auto关键字允许编译器从初始化表持局部作用域,但生命周期延伸到整个程序静达式推导变量类型auto x=10;//x推导为int态全局变量限制了其作用域为当前文件静态变类型auto对于复杂类型特别有用,如auto量初始化一次且存储在静态数据区it=map.begin;理解变量的作用域和生命周期对于编写正确的C++程序至关重要变量作用域决定了变量在程序的哪些部分可见,而生命周期决定了变量何时创建和销毁不同类型的变量有不同的存储位置局部变量通常在栈上,全局变量和静态变量在静态数据区,动态分配的对象在堆上栈和堆内存管理栈空间堆空间栈是一种自动管理的内存区域,用于存储局部变堆是一种动态内存区域,程序运行时可按需分量和函数调用信息特点配特点•自动分配和释放,不需要手动管理•需要手动申请和释放,使用new/delete•大小通常受限,几MB至几十MB•大小通常只受系统总内存限制•访问速度快,分配效率高•访问相对较慢,有内存碎片风险•LIFO后进先出原则组织内存•可以存储生命周期不确定的大对象内存管理实践新建堆对象T*ptr=new T;新建堆数组T*arr=new T[size];释放堆对象delete ptr;释放堆数组delete[]arr;智能指针std::unique_ptr,std::shared_ptrC++提供了直接的内存管理能力,这是其优势也是挑战内存管理不当会导致常见问题如内存泄漏(忘记释放内存)、悬挂指针(使用已释放的内存)、缓冲区溢出(写入超出分配范围)等这些问题可能导致程序不稳定或安全漏洞面向对象基础类与对象对象类的实例,代表具体实体类定义对象属性与行为的模板面向对象思想封装、继承、多态三大核心概念类是C++面向对象编程的核心,使用class或struct关键字定义类封装了数据(属性)和操作这些数据的函数(方法),形成一个自包含的单元例如,一个简单的学生类定义class Student{private:std::string name;int age;float gpa;public:Studentstd::string n,int a:namen,agea,gpa
0.0{}void studystringsubject;float getGPAconst{return gpa;}};类的成员与访问控制公有成员public私有成员private可以被任何函数访问的成员,通常是类的接口部分仅能被类内部和友元访问的成员,提供封装用于定义类对外提供的服务,如公有方法、API函数用于定义类内部的实现细节,如数据成员示例示例public:private:void setNamestd::string n;std::string name;std::string getNameconst;double balance;保护成员protected类似于私有成员,但可以被派生类访问用于需要被继承但不应直接对外暴露的成员示例protected:void updateInternalState;int status;访问控制是实现封装的关键机制,它将类的内部实现与外部接口分离良好的封装实践是将数据成员声明为私有,通过公有方法提供受控访问这样可以保证数据一致性,允许未来实现变更而不影响用户代码,也便于增加验证逻辑struct关键字也可以用于定义类,区别在于struct默认成员为public,而class默认为private在现代C++中,struct通常用于简单的数据结构,而class用于有复杂行为的对象构造函数与析构函数构造函数创建对象时自动调用,初始化对象状态对象生命周期对象创建后到销毁前的使用阶段析构函数对象销毁时自动调用,释放资源构造函数是特殊的成员函数,与类同名且无返回类型,用于初始化对象C++支持多种类型的构造函数
1.默认构造函数无参数或所有参数都有默认值
2.有参构造函数接受特定参数初始化对象
3.复制构造函数从同类型对象创建新对象
4.移动构造函数C++11从临时对象高效构造新对象
5.初始化列表构造函数C++11接受初始化列表参数构造函数可以使用成员初始化列表高效初始化成员Rectangleint w,int h:widthw,heighth{}指针thisthis指针概念this是一个隐含的指针,指向调用成员函数的对象每个非静态成员函数都有一个隐藏的this参数,它指向调用该函数的具体对象实例this指针的类型是ClassName*const,表示指针本身不能被修改(指向的对象固定),但指向的对象内容可以修改链式调用this指针常用于实现方法链(也称为流式接口),通过返回*this实现连续调用多个方法Student setNamestringname{this-name=name;return*this;}调用示例student.setName李四.setAge
22.setGPA
3.8;其他应用场景解决成员变量与参数同名冲突void setWidthintwidth{this-width=width;}在类内部判断两个对象是否相同bool equalsconstMyClass other{return this==other;}实现类的复制或移动赋值运算符this指针是C++面向对象机制的重要部分,它使得对象能够识别自己是谁,访问自己的成员this指针是隐式存在的,除非需要明确引用当前对象,否则不需要显式使用在const成员函数中,this指针类型是const ClassName*const,表示指向的对象内容也不能修改静态成员静态数据成员使用static关键字声明的类成员变量,所有对象共享一个实例必须在类外部定义和初始化int ClassName::staticVar=0;C++17允许内联初始化static inlineint count=0;静态成员函数static关键字声明的成员函数,与类本身而非特定对象关联不能访问非静态成员,没有this指针可以直接通过类名调用ClassName::staticFunction;应用场景跟踪类的所有实例数量实现单例模式或共享资源提供不需要对象实例的工具函数静态成员是类定义的一部分,但不属于任何特定的对象实例静态数据成员存储在全局数据区而非对象内存中,所有该类的对象共享同一个静态成员这使得静态成员成为在对象间共享信息的理想方式静态成员函数不依赖于任何对象实例,因此没有this指针,只能访问类的静态成员和全局数据静态成员函数常用于实现与类相关但不需要访问对象状态的功能,如工厂方法或辅助函数示例实现计数器跟踪对象创建次数类的继承基类父类提供被继承的属性和方法基类应该设计为包含所有派生类共有的特性,通常会包含虚函数以支持多态基类设计中要考虑派生类可能进行的扩展和修改派生类子类通过继承获取基类的特性,同时可以添加新特性或修改继承的行为派生类声明语法class Derived:[访问修饰符]Base{...};访问修饰符可以是public、protected或private,默认为private继承类型单继承派生类只有一个直接基类多继承派生类有多个直接基类,语法为class Derived:public Base1,protected Base2{...};多继承可能导致菱形继承问题,通过虚拟继承解决继承是面向对象编程的核心机制之一,允许新类基于现有类构建,复用代码并形成层次结构通过继承,派生类自动获得基类的公有和保护成员,但访问权限可能会因继承类型而改变不同继承类型的影响
1.public继承基类的public→派生类public,protected→protected,最常用
2.protected继承基类的public→派生类protected,protected→protected
3.private继承基类的public和protected都变为派生类private多态与虚函数函数重写虚函数派生类重新实现基类虚函数C++11引入override关键使用virtual关键字声明的成员函数,允许派生类重写字明确标记重写的函数,有助于避免错误void其行为基类声明虚函数,派生类提供具体实现,实draw override;函数签名(参数列表和const属现一个接口,多种实现性)必须与基类完全匹配纯虚函数与抽象类动态绑定声明为virtual voidfunc=0;的函数是纯虚函数通过基类指针或引用调用虚函数时,实际调用的函数包含纯虚函数的类是抽象类,不能直接实例化,只能取决于指向的对象类型,而非指针类型这称为动态用作基类抽象类定义接口,强制派生类提供实现绑定或晚绑定,是多态的核心机制多态是面向对象编程的核心概念,允许使用统一接口处理不同类型的对象C++通过虚函数实现运行时多态,使得基类指针可以根据指向的实际对象类型调用适当的函数版本示例Shape*shape=new Circle;shape-draw;//调用Circle::draw而非Shape::draw友元函数与友元类友元是C++中一种特殊的访问控制机制,允许函数或类访问另一个类的私有和保护成员通过在类定义中使用friend关键字声明友元关系class MyClass{private:int privateData;friend voidfriendFunctionMyClass obj;//友元函数声明friend classFriendClass;//友元类声明};友元函数可以是普通函数或另一个类的成员函数,它能直接访问声明它为友元的类的所有成员,包括私有成员友元类的所有成员函数都能访问声明它为友元的类的所有成员友元关系不是对称的(A是B的友元不意味着B是A的友元),也不是可传递的(A是B的友元,B是C的友元,不意味着A是C的友元)友元在某种程度上破坏了封装性,应谨慎使用,通常用于需要密切合作的类之间或特殊操作(如运算符重载)运算符重载成员函数重载在类内部定义运算符函数class Complex{public:Complex operator+const Complexrhs const{return Complexreal+rhs.real,imag+rhs.imag;}};使用Complex c=c1+c2;//调用c
1.operator+c2友元函数重载定义为类的友元函数friend Complexoperator+const Complexlhs,const Complexrhs{return Complexlhs.real+rhs.real,lhs.imag+rhs.imag;}适用于需要同时访问两个类对象私有成员的情况常见重载运算符算术运算符+,-,*,/赋值运算符=,+=,-=比较运算符==,!=,,递增递减++,--下标[]函数调用流操作,运算符重载使得用户自定义类型可以像内置类型一样使用C++运算符,提高代码的直观性和可读性例如,通过重载+运算符,可以实现复数相加Complex c3=c1+c2;而不必调用c3=c
1.addc2重载运算符的限制不能改变运算符原有的语法结构(参数数量)、优先级和结合性;不能创建新运算符;某些运算符不能重载(如:,::,.,.*);某些运算符只能作为成员函数重载(如=,[],,-)模板编程函数模板类模板定义一个可处理不同数据类型的函数框架语法定义一个可用于不同数据类型的类语法template templateTmaxTa,T b{class Vector{return aba:b;private:}T*data;int size;调用max10,20;//T实例化为intpublic:max
3.14,
2.71;//T实例化为doubleVectorint s;编译器为每种使用的类型生成具体函数实现T operator[]int i;};使用Vector numbers10;Vector names5;模板是C++泛型编程的基础,允许编写与类型无关的代码,提高代码复用性函数模板适用于实现通用算法,类模板适用于创建通用容器或数据结构与宏不同,模板是类型安全的,且支持更复杂的操作模板支持多个类型参数、非类型参数(如整数常量)和模板特化(为特定类型提供优化实现)模板特化示例template boolmaxbool a,bool b{//针对bool类型的特化return a||b;//逻辑或代替比较大小}异常处理抛出异常使用throw关键字抛出异常对象,表示发生错误情况if denominator==0{throw std::runtime_error除数不能为零;}可以抛出任何类型的异常,但推荐使用标准异常类或自定义异常类捕获异常使用try-catch结构捕获和处理异常try{//可能抛出异常的代码result=dividea,b;}catch conststd::exception e{//处理异常std::cerr错误e.whatstd::endl;}异常层次结构C++标准库提供了异常类层次结构,基类是std::exception常用派生类包括std::runtime_error、std::logic_error等可以创建自定义异常类继承自std::exception异常处理提供了结构化的错误处理机制,使错误检测代码与错误处理代码分离,提高可读性和可维护性异常特别适合处理不可预期的错误情况,而不适合日常的流程控制异常的传播如果函数中抛出异常但未被捕获,异常会沿调用栈向上传播,直到遇到能处理该异常的catch块或到达main函数如果异常未被捕获,程序将调用std::terminate终止简介STL算法通用算法集合,独立于具体容器迭代器连接容器与算法的通用接口容器管理集合数据的数据结构标准模板库STL是C++标准库的核心部分,提供了通用容器、算法、迭代器和函数对象STL基于泛型编程思想,通过模板实现与类型无关的代码复用,大大提高了开发效率STL的主要组件
1.容器管理集合数据的模板类包括-序列容器vector(动态数组)、list(双向链表)、deque(双端队列)-关联容器set/multiset(集合)、map/multimap(键值对映射)-无序容器C++11unordered_set/map(基于哈希表)
2.算法操作容器元素的通用函数如sort、find、for_each等,定义在algorithm头文件中
3.迭代器提供容器元素访问的统一接口,类似于智能指针
4.函数对象可作为算法参数的可调用对象,实现自定义行为vector动态数组用法创建与初始化std::vector nums;//空vectorstd::vector nums10;//包含10个默认值0元素std::vector nums{1,2,3,4,5};//初始化列表std::vector copy=nums;//复制构造添加与删除元素nums.push_back6;//在末尾添加元素nums.pop_back;//移除末尾元素nums.insertnums.begin+2,10;//在指定位置插入nums.erasenums.begin+1;//删除指定位置元素nums.clear;//清空所有元素访问与遍历int first=nums
[0];//下标访问(无边界检查)int safe=nums.at1;//at方法(有边界检查)int last=nums.back;//访问最后一个元素//使用迭代器遍历forauto it=nums.begin;it!=nums.end;++it{}//C++11范围for循环forauto num:nums{}std::vector是C++标准库中最常用的容器,实现了动态大小的数组它在内存中连续存储元素,支持随机访问(常数时间),在末尾添加和删除元素通常很快(均摊常数时间)vector会自动管理内存,随着元素增加自动扩容vector的关键特性包括自动内存管理、快速随机访问和迭代器支持常用方法还包括-size返回当前元素数量-capacity返回当前分配的存储空间大小-reserven预留n个元素的存储空间,不创建元素-resizen调整大小为n个元素,可能创建新元素或删除多余元素-empty检查容器是否为空map关联容器基本操作遍历方式std::map实现了键值对映射,基于红黑树,键按顺序排列使用迭代器创建std::map scores;forauto it=scores.begin;it!=scores.end;++it{插入scores[张三]=95;或scores.insert{李四,88};std::coutit-first:it-secondstd::endl;访问int score=scores[王五];//如果键不存在,会创建并赋默}认值C++11范围for循环安全访问auto it=scores.find赵六;ifit!=scores.end{...}forconst auto pair:scores{std::coutpair.first:pair.secondstd::endl;}特性与变体std::map特点有序、不允许重复键、基于平衡二叉树Olog n操作相关容器-std::multimap允许重复键的map-std::unordered_map基于哈希表实现,提供平均O1访问,但无序自定义键类型需要提供比较运算符或哈希函数std::map是实现关联数组和查找表的理想选择,它以键为索引存储和检索值map中的元素按键排序,这在需要有序遍历时很有用map的所有操作(插入、删除、查找)都具有对数时间复杂度Olog n,对于大多数应用来说足够高效新特性概览C++11C++11是C++语言的重大更新,引入了大量现代特性,使语言更加强大和易用主要新特性包括
1.自动类型推导auto让编译器从初始化表达式推导变量类型auto i=42;//i推导为int类型auto iter=container.begin;//避免复杂迭代器类型声明
2.基于范围的for循环简化容器遍历forconst autoelem:container{/*处理elem*/}
3.智能指针-std::unique_ptr独占所有权,不能复制-std::shared_ptr共享所有权,引用计数-std::weak_ptr不影响引用计数的shared_ptr观察者表达式Lambda基本语法捕获机制Lambda表达式是匿名函数,语法结构为捕获列表指定lambda可以访问的外部变量[捕获列表]参数列表-返回类型{函数体}[=]按值捕获所有外部变量简单示例auto sum=[]inta,int b{return a+b;};[]按引用捕获所有外部变量调用int result=sum3,4;//结果为7[x,y]按值捕获x,按引用捕获y返回类型通常可以省略,由编译器推导[=,z]除z按引用外,其余按值捕获[this]捕获当前对象(在成员函数中)常见用途STL算法参数std::sortv.begin,v.end,[]inta,int b{return ab;};事件处理与回调button.setOnClickListener[]{updateUI;};简化局部逻辑auto found=std::find_ifv.begin,v.end,[]int n{return n%2==0;};Lambda表达式是C++11引入的强大特性,允许在需要函数对象的地方直接定义内联函数,代码更加简洁紧凑Lambda本质上是一个匿名函数对象(闭包),生成一个拥有operator的类Lambda使得函数式编程风格在C++中更加自然它特别适合定义简短的、一次性使用的函数对象,避免了显式定义函数或函数对象类的开销在STL算法中使用Lambda可以显著提高代码可读性,例如自定义排序规则、过滤条件或转换操作智能指针与内存安全std::unique_ptr std::shared_ptr std::weak_ptr独占所有权的智能指针,资源只能由一个指针拥有共享所有权的智能指针,使用引用计数std::shared_ptr的观察者,不增加引用计数示例std::unique_ptr pnew int10;示例std::shared_ptr p1newint20;示例std::weak_ptr wp=p1;C++14更简洁auto p=std::make_unique10;推荐auto p1=std::make_shared20;使用前需要检查并锁定ifauto sp=wp.lock{/*使用sp*/}不支持复制,但可以移动auto p2=std::movep;可以安全复制autop2=p1;//引用计数增加主要用途打破循环引用、缓存、观察者模式适用于独占资源或明确所有权的场景当引用计数归零时自动释放资源适用于共享资源或不明确所有权的场景智能指针是现代C++内存管理的核心工具,通过RAII资源获取即初始化原则实现自动资源管理它们在对象离开作用域时自动调用析构函数释放资源,有效防止内存泄漏、野指针和资源泄露等常见问题使用智能指针的最佳实践
1.优先使用make_unique/make_shared创建,而非直接new
2.默认选择unique_ptr,只有需要共享所有权时才用shared_ptr
3.避免使用裸指针管理资源,即使是临时性的
4.使用weak_ptr避免shared_ptr循环引用
5.自定义删除器处理特殊资源(如文件句柄、互斥锁)多线程支持互斥与同步防止数据竞争的同步原语线程创建与管理std::mutex mtx;C++11引入std::thread类表示单个执行线程mtx.lock;//加锁void workerintid{/*工作函数*/}//临界区代码std::thread t1worker,1;//创建并立即开始执行mtx.unlock;//解锁t
1.join;//等待线程完成更安全的RAII锁t
1.detach;//分离线程(后台运行)std::lock_guard lockmtx;可重入锁std::recursive_mutex条件变量future与异步任务用于线程间通信和等待特定条件管理异步操作结果std::condition_variable cv;std::future fut=std::asyncstd::launch::async,calculateValue;std::unique_lock lockmtx;//等待结果//等待条件满足int result=fut.get;cv.waitlock,[]{return ready;};std::promise用于手动设置异步结果//通知等待线程std::packaged_task封装可调用对象cv.notify_one;//或cv.notify_all;C++11标准库引入了全面的多线程支持,让开发者无需依赖平台特定API即可编写可移植的并发程序这些工具位于thread、mutex、condition_variable和future等头文件中多线程编程的主要挑战是避免数据竞争和死锁数据竞争发生在多个线程同时访问共享数据且至少一个线程进行写操作时;死锁则是线程互相等待对方持有的资源使用适当的同步机制(如互斥锁)和遵循良好实践(如锁的顺序一致性)可以避免这些问题文件输入输出文件输出文件输入二进制文件操作使用ofstream写入文件使用ifstream读取文件读写二进制数据#include std::ifstream inFiledata.txt;//写入std::ofstream outFiledata.txt;ifinFile.is_open{std::ofstream outdata.bin,std::ios::binary;ifoutFile.is_open{std::string line;MyStruct data{1,
2.5};outFileHello,World!std::endl;int number;out.writereinterpret_castdata,sizeofdata;outFile
423.14std::endl;double value;//读取outFile.close;//可选,析构时自动关闭//按行读取std::ifstream indata.bin,std::ios::binary;}std::getlineinFile,line;MyStruct readData;打开模式std::ofstream outfile.txt,std::ios::out|//格式化读取in.readreinterpret_castreadData,std::ios::app;sizeofreadData;inFilenumbervalue;}C++的文件I/O建立在流stream的概念上,与标准I/Ocin,cout使用相同的接口文件流类定义在fstream头文件中,主要包括std::ifstream(输入文件流)、std::ofstream(输出文件流)和std::fstream(可同时输入输出)文件操作常见任务包括检查文件是否成功打开is_open、检测文件结束eof、错误处理fail,bad和文件定位seekg,seekp,tellg,tellp文件流支持与标准流相同的格式化功能,如操纵符std::setw,std::setprecision等常用应用领域C++系统级编程C++广泛应用于操作系统、驱动程序和系统工具开发Windows、Linux、macOS等操作系统的关键组件大量使用C++低级别内存控制和高性能优化能力使C++成为系统编程的理想选择游戏与图形渲染游戏引擎(如Unreal Engine、Unity的C++部分)、3D渲染器和物理模拟普遍采用C++高性能要求和硬件加速接口(如DirectX、OpenGL)的可用性使C++成为游戏开发的主导语言金融与高频交易银行、证券交易所和投资机构大量采用C++开发交易系统和金融模型微秒级延迟要求和大数据处理能力使C++在金融科技领域占据重要地位高性能计算科学计算、物理模拟、气象预报等计算密集型应用依赖C++的执行效率并行计算库和向量化优化使C++适合处理大规模数值问题C++的多范式特性使其在各种领域都有广泛应用除了上述领域,C++还广泛用于嵌入式系统开发(智能设备、物联网)、数据库引擎实现(MySQL、MongoDB的核心)、电信设备和网络协议栈、航空航天软件以及机器人控制系统各应用领域对C++的不同特性有不同偏好系统编程侧重内存控制和性能;游戏开发利用面向对象特性管理复杂实体;金融应用重视模板编程实现通用算法;嵌入式系统关注低内存占用和确定性行为程序调试技巧C++使用断点和调试器断点是调试的基础工具,允许在特定代码位置暂停程序执行现代IDE(如VisualStudio、CLion)提供图形化断点设置界面调试时,可以检查变量值、调用栈和内存状态,也可以使用条件断点(仅在特定条件满足时触发)和数据断点(当变量值改变时触发)常见语法错误识别编译错误通常由语法问题引起,常见包括缺少分号、括号不匹配、未声明变量、类型不匹配等理解编译器错误信息是关键技能对于复杂错误(尤其是模板相关),从第一个错误开始修复,因为后续错误可能是连锁反应逻辑错误排查逻辑错误更难发现,因为程序能编译运行但结果不正确常见问题包括边界条件处理不当、指针/引用错误、资源泄漏和内存损坏使用单元测试、断言assert和静态分析工具可以帮助发现这类问题调试内存问题的专用工具包括Valgrind和AddressSanitizer有效的C++调试策略包括输出调试(使用cout或专用日志库记录关键信息)、二分查找法(逐步缩小问题范围)、代码评审(第三方检查)和单步执行(观察程序流程)对于多线程程序,调试难度更大,可能需要特殊工具帮助定位竞争条件和死锁预防是最好的调试遵循良好的编码规范、使用静态类型检查、限制变量作用域、使用RAII管理资源、编写单元测试,都能减少bug现代C++特性(如智能指针)也显著减少了内存管理错误典型面试与考研题型经典项目案例C++12学生成绩管理系统银行账户模拟系统适合初学者的入门项目,涉及C++核心概念类的设计与实进阶项目,强化OOP概念继承与多态(不同账户类型)、现、文件I/O操作、STL容器应用实现学生信息的添加、查异常处理(错误操作)、线程安全(并发交易)实现账户询、修改、统计分析等功能,练习封装和模块化设计管理、存取款、转账、利息计算等银行业务功能3贪吃蛇游戏开发趣味性项目,综合应用控制台或图形界面编程、游戏循环设计、碰撞检测算法、随机数生成扩展功能可包括难度设置、记分板、特殊食物效果等,练习事件驱动编程这些项目不仅提供了应用C++知识的实际环境,还培养解决问题的能力和软件设计思维项目开发过程建议遵循清晰的步骤需求分析→设计类图→编写核心功能→测试与调试→功能扩展更高级的项目可以考虑简易数据库引擎(B树索引、事务管理)、网络聊天应用(TCP/IP编程、多线程)、简易编译器(词法分析、语法分析)或图像处理应用(算法实现)这些项目能够深入锻炼高级C++概念和软件工程能力权威书籍和资料C++C++学习过程中,选择合适的学习资料至关重要以下是广受推荐的经典书籍
1.入门经典《C++Primer》(第5版)由Stanley Lippman等编写,全面系统地介绍C++基础知识,特别适合初学者内容丰富但较为庞大,建议选择性阅读
2.最佳实践《Effective C++》和《More EffectiveC++》由Scott Meyers编写,不是入门书籍,而是提供编写高质量C++代码的实用指南和最佳实践,帮助避免常见陷阱
3.语言设计者著作《C++程序设计语言》和《C++语言导学》均由C++创始人Bjarne Stroustrup编写,提供对语言的权威解释和设计思想尤其是《C++语言导学》篇幅适中,是了解现代C++的理想选择总结与学习建议多写代码+勤查资料重点掌握面向对象与STLC++学习最有效的方法是项目实践从小项目面向对象是C++的核心特性,深入理解封装、开始,逐步挑战更复杂的问题;遇到困难时查继承和多态;STL是日常编程的强大工具箱,阅官方文档和参考资料,培养自主解决问题的熟练掌握常用容器(vector、map等)和算能力每周至少编写200-300行代码,持续法这两方面的知识占C++日常应用的80%以积累经验问题解决过程比最终结果更有价值上,是求职面试和实际工作的重点阅读开源代码提升水平学习优秀的C++项目源码是提高编程能力的捷径从简单项目开始,逐步挑战大型项目;关注代码组织方式、设计模式应用和性能优化技巧GitHub上有大量高质量C++项目,如Boost库、LLVM编译器等学习C++是一个循序渐进的过程建议先掌握基础语法和面向对象概念,然后学习STL和常用库,最后探索高级主题(如模板元编程、并发编程)避免一开始就钻研过于复杂的特性,以免陷入细节而忽略整体架构学习策略上,结合自己的学习风格选择适合的方法视觉学习者可以利用图表和视频教程;实践型学习者应多编写代码并分析结果;分析型学习者则可以深入研究语言规范和设计理念无论采用何种方式,坚持练习和解决实际问题是提高的关键课后答疑及讨论提问与反馈学习过程中遇到的问题是宝贵的学习资源鼓励大家在课后整理自己的疑问,通过邮件或在线平台提交我们将在下次课程开始时解答典型问题,或安排专门的答疑环节反馈也帮助我们不断改进课程内容和教学方法组建学习小组编程学习中,小组讨论和协作能显著提高学习效率建议3-5人组成学习小组,定期讨论课程内容,共同解决编程挑战研究表明,向他人解释概念是巩固知识的最佳方式之一,小组环境为此提供了理想平台参与线上社区课程配套建立了在线讨论群,扫描下方二维码加入群内有助教和高年级学长提供支持,大家可以分享资源、讨论难点、组织线下活动活跃参与者将有机会获得额外的项目指导和实习推荐机会本课程后续计划包括每周一次的选修实验课,聚焦实际编程技能;每月一次的行业嘉宾讲座,分享C++在不同领域的应用实践;期末大型项目实践,由学生自选题目或从推荐列表中选择,展示所学知识的综合应用能力对于学有余力的同学,我们准备了进阶学习路径建议,包括深入研究某个专业领域(如游戏开发、系统编程)的C++应用,或拓展学习相关技术(如计算机图形学、并行计算)学习计划可根据个人兴趣和职业规划定制,欢迎单独咨询。
个人认证
优秀文档
获得点赞 0