还剩48页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
高级教程C++欢迎参加高级C++教程,这门课程将带您从基础知识到高级技术,全面掌握C++编程语言无论您是初学者还是有经验的开发者,本课程都将为您提供深入的见解和实用技能,帮助您成为C++专家我们将系统地探索C++的核心概念、面向对象编程原则、标准模板库STL、并发编程等高级主题,通过实际案例和项目实践加深您的理解和应用能力课程概述全面指南适合多层次学习者实用案例与最佳实践现代标准本课程提供从基础到高级无论您是刚开始接触编程通过真实世界的项目案例课程内容紧跟的C++编程全面指南,涵盖的初学者,还是希望提升和行业最佳实践,您将学C++11/14/17/20等现代标语言核心特性、标准库和技能的进阶开发者,本课习如何应用C++解决实际问准,确保您掌握最新的语现代C++的新特性我们将程都为您量身定制了合适题,提高代码质量和性言特性和编程技术,保持通过循序渐进的方式,帮的学习路径和内容深度能竞争力助您建立坚实的知识基础教学目标掌握C++核心语法和高级特性深入理解C++的基础语法结构和高级特性,包括模板元编程、智能指针、右值引用等现代C++特性,为复杂应用开发打下坚实基础理解面向对象编程原则全面掌握封装、继承和多态三大面向对象编程原则,学习如何设计可维护、可扩展的类层次结构,实现灵活的软件架构熟练运用STL和模板编程深入了解标准模板库的各种容器、算法和迭代器,掌握泛型编程技术,提高代码的复用性和抽象能力培养良好的编码习惯和调试技能形成规范的编码风格,学习高效的调试方法和性能优化技巧,提高程序的可靠性和执行效率简介C++通用高效多范式支持广泛应用C++是一种功能强大、C++支持过程式编程、C++广泛应用于操作系性能卓越的编程语面向对象编程、泛型统、游戏引擎、高性言,能够适应从系统编程和函数式编程等能服务器、金融系底层到应用层的各种多种编程范式,为开统、嵌入式设备等需开发需求,提供接近发者提供灵活的设计要高效性能的领域,硬件的效率和高级语选择是众多关键系统的核言的抽象能力心语言相比C语言,C++增强了许多特性,包括类、异常处理、模板、标准模板库等,同时保持了与C语言的兼容性,使其成为兼具高效和抽象能力的优秀语言发展历史C++11979年丹麦计算机科学家Bjarne Stroustrup开始设计C withClasses,这是C++的前身,旨在为C语言添加面向对象的能力,同时保持C语言的高效性21985年第一版C++正式发布,包含了类、派生、强类型检查、内联函数和默认参数等特性,为现代软件开发奠定了基础31998年C++98标准正式确立,首次统一了C++语言规范,添加了模板、异常处理、命名空间等重要特性,使C++成为主流的系统开发42011年语言C++11标准发布,带来了重大更新,包括自动类型推导、Lambda表达式、右值引用、智能指针等现代特性,大幅提高52014/17/20了开发效率和代码安全性C++持续更新,C++
14、C++17和C++20标准相继推出,引入了协程、概念、模块等创新特性,不断优化语言能力和开发体验开发环境设置主流IDE编译器选择•Visual Studio:微软开发的功能强大的集成开发环境,提供全面的C++支•GCC:GNU编译器集合,开源且跨平台,支持最新C++标准持和丰富的调试工具•Clang:基于LLVM的现代编译器,提供更友好的错误信息和快速编译速•CLion:JetBrains开发的跨平台IDE,具有智能代码补全和强大的重构功度能•MSVC:微软Visual C++编译器,与Windows平台深度集成•Qt Creator:专为Qt框架设计的轻量级IDE,适合GUI应用开发构建工具版本控制与协作•CMake:跨平台的构建系统生成器,简化多平台项目管理•Git:分布式版本控制系统,支持多人协作开发•Make:传统的Unix构建工具,通过Makefile定义构建规则•GitHub/GitLab:代码托管平台,提供项目管理和协作功能基础语法概览变量声明与初始化基本数据类型与范围运算符与表达式C++提供多种变量声明和初始化方式,包括C++支持丰富的基本数据类型,包括整型、C++继承并扩展了C语言的运算符集,同时传统的赋值初始化、构造函数初始化和浮点型、字符型和布尔型等,每种类型都支持运算符重载,使开发者能够为自定义C++11引入的统一初始化语法良好的初始有特定的内存占用和取值范围,选择合适类型定义直观的操作语法,提高代码的可化习惯可以避免未定义行为和潜在错误的数据类型对性能和内存使用至关重要读性和表达能力C++推荐使用规范的注释和一致的编码风格,包括适当的缩进、命名约定和文档注释,这有助于提高代码的可维护性和团队协作效率良好的编码习惯是成为专业C++开发者的重要标志数据类型详解类型大小字节值范围用途char1-128to127字符存储int4-2^31to2^31-1整数计算float
43.4E±387位精度单精度浮点double
81.7E±30815位精双精度浮点度bool1true/false逻辑判断C++中的常量使用const关键字声明,而字面量则是源代码中的固定值,如整数、浮点数、字符和字符串字面量C++11引入了用户自定义字面量,允许为自定义类型创建字面值表示类型转换在C++中分为隐式转换和显式转换C++提供了static_cast、dynamic_cast、const_cast和reinterpret_cast四种安全的类型转换操作符,比C风格的类型转换更加类型安全sizeof运算符用于获取数据类型或变量的字节大小,这对于理解内存分配和管理非常重要,特别是在处理数组、结构体和类对象时控制结构条件语句if-else和switch-case用于根据条件执行不同代码路径循环结构for、while和do-while提供重复执行代码块的能力跳转语句break、continue和return控制程序执行流程异常处理try-catch-throw机制提供结构化错误处理C++的条件语句允许程序根据不同条件执行不同的代码块if-else适合简单的二分支或多分支条件,而switch-case则更适合多值匹配的场景,尤其是处理枚举值时更加清晰循环结构是程序重复执行某段代码的机制for循环适合已知迭代次数的情况,while适合基于条件的循环,do-while确保至少执行一次循环体C++11引入的范围for循环简化了容器遍历异常处理提供了一种统一管理错误的机制,使错误检测与处理代码分离,提高代码的可读性和健壮性合理使用异常能够构建更加健壮的程序函数基础函数声明与定义函数声明指定函数名、返回类型和参数列表,而函数定义则包含完整的函数实现C++允许将声明和定义分离,这是头文件与源文件分离的基础函数原型通常放在头文件中,而实现则放在源文件中参数传递机制C++提供三种参数传递方式值传递拷贝参数值、指针传递传递内存地址和引用传递创建参数别名选择合适的传递方式对于性能和功能都至关重要,尤其是处理大型对象时,引用传递可以避免不必要的拷贝开销返回值类型与返回方式函数可以返回任何有效的C++类型,包括基本类型、指针、引用和用户定义类型C++11引入了返回值类型后置语法和自动返回类型推导,简化了复杂返回类型的函数声明现代C++鼓励使用返回值优化来高效返回对象函数重载原理函数重载允许多个同名函数拥有不同的参数列表,这是C++多态性的一种形式编译器通过参数类型的差异来区分不同的重载函数,称为名称修饰Name Mangling返回类型不同但参数相同的函数不构成重载数组与指针数组定义与初始化指针概念与应用数组是存储同类型元素的连续内存块C++支持多种数组初始化方式,指针是存储内存地址的变量,通过解引用操作符*访问指向的数据指包括列表初始化和部分初始化数组大小必须是编译期常量,且一旦创针是C++中最强大也最危险的特性之一,使用不当可能导致内存泄漏或建,大小不可改变多维数组通过嵌套数组实现,内存布局为行优先顺访问无效内存空指针nullptr表示指针不指向任何有效对象序int value=42;int numbers
[5]={1,2,3,4,5};int*ptr=value;//取地址char name[]=C++;//自动确定大小*ptr=100;//修改指向的值int matrix
[3]
[3]={{1,2,3},{4,5,6},{7,8,9}};int*nullPtr=nullptr;//C++11空指针指针算术运算允许指针通过加减整数进行移动,这在数组操作中特别有用指针算术考虑指向类型的大小,移动一个单位表示移动一个元素的大小,而不是一个字节数组名在大多数表达式中会衰变为指向首元素的指针,但sizeof、等运算符例外数组与指针密切相关但不完全等同,理解它们的关系对于有效管理内存和避免常见错误至关重要引用与常量引用的概念与应用const关键字与常量引用是对象的别名,必须初始化且不能重const定义不可修改的变量,提高代码安新绑定到其他对象全性并表达设计意图const成员函数const与指针的组合保证不修改对象状态,可被const对象调const指针和指向const的指针提供不同级用别的不可变性保证引用在C++中广泛用于函数参数和返回值,避免了不必要的对象拷贝,提高了性能与指针不同,引用没有空引用的概念,必须始终指向有效对象,且不需要解引用操作符就能访问被引用对象const修饰符在接口设计中扮演重要角色,它明确表达了不可修改的意图,使编译器能够捕获意外的修改尝试现代C++推荐尽可能使用const,特别是在函数参数、返回值和成员函数中,这有助于编写更安全、更清晰的代码动态内存管理new与delete操作符用于单个对象的动态分配与释放动态数组操作使用new[]和delete[]创建和销毁动态数组内存泄漏问题忘记释放动态内存导致的资源浪费智能指针基础自动管理动态内存的现代C++工具动态内存管理是C++中最强大也最容易出错的特性之一new操作符在堆上分配内存并调用构造函数,而delete则调用析构函数并释放内存与C语言的malloc/free不同,new/delete能正确处理对象的构造和析构内存泄漏是常见的内存管理问题,发生在分配的内存没有被适当释放的情况下长时间运行的程序中,内存泄漏会导致可用内存不断减少,最终可能导致程序崩溃常见原因包括提前返回、异常、指针重新赋值前忘记释放旧内存等为解决手动内存管理的问题,现代C++引入了智能指针,包括unique_ptr、shared_ptr和weak_ptr,它们能自动管理内存生命周期,大大减少内存泄漏的风险智能指针是实现RAII资源获取即初始化原则的重要工具面向对象编程基础多态通过接口实现不同形式的行为继承子类获取父类属性和方法的机制封装隐藏内部细节,只暴露必要接口面向对象编程OOP是C++的核心范式之一,通过类和对象的概念将数据和行为组织在一起类是对象的蓝图,定义了数据成员和方法;对象则是类的实例,拥有具体的状态和行为封装是面向对象的基础特性,通过访问控制实现数据隐藏,保护内部状态不被外部直接访问,减少模块间的依赖继承建立了类之间的层次关系,实现代码重用和是一种的关系模型多态则允许通过统一接口处理不同类型的对象,增强了代码的灵活性和可扩展性UML类图是表示类结构和关系的标准化图形语言,通过符号表示类、属性、方法以及类之间的继承、组合、聚合等关系对象生命周期管理涉及对象的创建、使用和销毁过程,合理管理对象生命周期对于避免资源泄露至关重要类的定义与实现成员变量与成员函数类包含数据成员属性和成员函数方法,共同定义了类的状态和行为数据成员存储对象的状态信息,而成员函数定义了对象可执行的操作成员函数可以访问同一对象的所有成员,包括私有成员访问控制修饰符C++提供三种访问级别private仅类内部访问、protected类内部和子类访问和public任何地方都可访问通过访问控制,实现数据隐藏和接口暴露,是封装原则的重要实现手段默认情况下,类成员为private,结构体成员为public构造函数与析构函数构造函数在对象创建时初始化对象状态,可以重载以支持不同的初始化方式析构函数在对象销毁时清理资源,确保不发生资源泄漏构造和析构是管理对象生命周期的关键机制this指针的使用this是隐含的指向当前对象的指针,每个非静态成员函数都能访问this用于区分成员变量和局部变量、返回当前对象引用支持链式调用,以及在实现中表明操作的是当前对象构造函数详解默认构造函数是不带参数的构造函数或所有参数都有默认值,当没有显式提供构造函数时,编译器会自动生成参数化构造函数接受一个或多个参数,允许在创建对象时提供初始状态拷贝构造函数接受同类型对象的常量引用作为参数,用于创建对象的副本移动构造函数C++11接受右值引用参数,通过窃取资源而非复制实现高效的对象创建,特别适合管理独占资源的类委托构造函数C++11允许一个构造函数调用同一类的另一个构造函数,避免代码重复初始化列表是构造函数的重要部分,它在函数体执行前初始化成员变量,对于const成员和引用成员尤为重要,同时也通常比在函数体内赋值更高效运算符重载运算符重载基本语法成员函数与非成员函数重载运算符重载允许用户定义类型的对象使用C++内置运算符,使代码更加直观和易读重运算符可以作为成员函数或非成员函数重载成员函数重载左操作数是对象本身载运算符本质上是具有特殊名称的函数,形式为operator@,其中@是要重载的运算this;非成员函数重载则需要显式接收所有操作数某些运算符如赋值=、下标[]、调符用、成员访问-只能作为成员函数重载class Complex{//非成员函数重载public:Complex operator*const Complexlhs,Complex operator+const Complexrhs const{const Complexrhs{return Complexreal+rhs.real,return Complexlhs.real*rhs.real-imag+rhs.imag;lhs.imag*rhs.imag,}lhs.real*rhs.imag+private:lhs.imag*rhs.real;double real,imag;}};常用重载运算符包括算术运算符+,-,*,/、比较运算符==,!=,,、赋值运算符=、复合赋值+=,-=、流操作符,等重载运算符应保持与内置类型运算符相似的语义,以符合用户期望,例如+应该表示某种形式的加法而非减法运算符重载存在一些限制,包括不能改变运算符优先级和结合性、不能重载不存在的运算符、不能改变运算符作用的对象数量、某些运算符不能重载如::,.*,.,:合理使用运算符重载可以提高代码的可读性,但过度使用可能导致混淆继承与派生基类与派生类关系继承建立了类之间的是一种关系,派生类继承基类的属性和行为,同时可以添加新成员或重写继承的成员这种层次结构使代码更易组织和复用基类也称为父类,派生类也称为子类,体现了概念上的层次关系访问控制与继承类型C++支持三种继承方式公有继承保持原有访问级别、保护继承公有成员变为保护和私有继承所有成员变为私有公有继承表示是一种关系,而私有和保护继承则更多用于实现细节,表示用一种实现的关系构造与析构顺序对象构造时,先调用基类构造函数,再调用派生类构造函数;析构时顺序相反,先调用派生类析构函数,再调用基类析构函数这确保了对象在任何时刻都处于有效状态,基类部分总是在派生类部分之前初始化完成虚继承与菱形问题菱形继承发生在一个类间接从同一基类继承多次,可能导致基类成员重复虚继承解决这个问题,确保无论多少条继承路径,基类的实例在派生类中只存在一份虚继承在标准库和复杂类层次中广泛使用多态性实现虚函数机制纯虚函数与抽象类虚函数是C++实现运行时多态的核心机制通过在基类中声明虚函数并在派生类中重写,可以实现动态绑定通过纯虚函数是没有实现的虚函数,声明形式为=0包含至少一个纯虚函数的类称为抽象类,不能直接实例化,只基类指针或引用调用成员函数时,执行的是对象实际类型的函数版本,而非指针类型的版本能作为基类使用抽象类定义接口,强制派生类提供特定功能的实现,是接口编程的基础class Shape{class AbstractShape{public:public:virtual void draw const{//纯虚函数coutShape::drawendl;virtual void draw const=0;}virtual double area const=0;virtual~Shape{}//虚析构函数virtual~AbstractShape{}};};class Circle:public Shape{//必须实现所有纯虚函数public:class Rectangle:public AbstractShape{voiddrawconst override{public:coutCircle::drawendl;voiddrawconst override{}//实现绘制矩形的代码};}doubleareaconst override{return width*height;}private:double width,height;};虚函数表vtable是C++实现虚函数的内部机制每个含有虚函数的类都有一个虚函数表,存储了该类虚函数的地址每个对象包含一个指向虚函数表的指针vptr,这使得对象知道调用哪个版本的虚函数这种机制增加了少量的空间和时间开销,但提供了强大的多态能力友元与嵌套类友元函数与友元类嵌套类的定义与访问局部类定义友元函数是可以访问类私有和保护成员的非成员嵌套类是定义在另一个类内部的类,用于表示仅局部类是定义在函数内部的类,作用域仅限于定函数友元类的所有成员函数都可以访问授予友对外部类有意义的类型嵌套类可以访问外部类义它的函数局部类不能使用函数中的非静态变元关系的类的私有成员友元关系不具有传递性的静态成员,但不能直接访问外部类的非静态成量,也不能定义静态成员局部类通常用于实现和继承性,必须显式声明友元打破了封装,但员嵌套类有助于组织代码结构,减少命名空间只在特定函数中使用的辅助功能,使代码更加封在特定情况下很有用,如运算符重载或需要高效污染,并表达类之间的紧密关系装和局部化访问多个类的私有成员友元机制应谨慎使用,过度使用会破坏封装性,增加类之间的耦合友元适合的场景包括需要高效访问私有成员的非成员运算符重载、需要共享实现细节的紧密协作类等在设计API时,应尽量减少友元的使用,保持类的独立性和封装性模板编程基础函数模板设计函数模板允许编写与类型无关的通用算法,编译器根据调用时的参数类型自动生成具体函数版本模板参数可以有默认值和约束条件C++20函数模板解决了代码复用问题,避免为不同类型编写几乎相同的函数templateT maxTa,T b{return aba:b;}//使用方式int m=max5,9;//T为intdouble d=max
3.4,
2.5;//T为double类模板定义与使用类模板提供了创建类型族的机制,使一个类设计可以适用于多种数据类型使用类模板时必须显式指定模板参数除非有默认值或使用CTAD类模板是STL容器和智能指针等核心库组件的基础templateclass Array{public:T operator[]int index{return data[index];}private:T data[Size];};//使用方式Array intArray;Array stringArray;//使用默认Size=10模板参数推导编译器能从函数调用的参数推导模板参数类型C++17引入类模板参数推导CTAD,允许从构造函数参数推导类模板参数C++20的概念Concepts进一步增强了模板参数约束和错误消息的清晰度模板特化与偏特化高级模板技术可变参数模板C++11引入的可变参数模板允许函数和类接受任意数量的参数通过参数包展开和递归模板实例化,可以处理不同类型和数量的参数这项技术是std::tuple、std::make_shared等现代C++功能的基础,也广泛用于函数转发和完美转发模板元编程基础模板元编程TMP是利用C++模板系统在编译期进行计算的技术TMP可实现编译期类型运算、条件逻辑和循环结构,生成高效代码虽然语法复杂,但用于性能关键应用可显著提升运行效率,因为将计算从运行时转移到编译时类型萃取技术类型萃取type traits提供了在编译期检查和修改类型属性的能力C++标准库的头文件包含丰富的类型萃取工具,用于检测类型是否为指针、引用、类等,以及移除引用、添加const等类型转换这使得编写适应不同类型的通用代码成为可能表达式模板表达式模板是一种避免临时对象创建的高级优化技术,主要用于数值计算库它通过将表达式表示为模板对象而非立即求值,允许编译器生成整个表达式的优化代码表达式模板能显著提高向量和矩阵运算等数值计算的性能STL容器迭代器STL随机访问迭代器支持任意跳跃访问,如vector、deque双向迭代器可前进和后退,如list、set、map前向迭代器只能向前移动,如forward_list输入/输出迭代器最基本的读写功能,如istream/ostream迭代器是C++容器的统一访问接口,将算法与容器分离,使算法可以作用于不同容器迭代器分为五类,具有层次关系输入/输出迭代器、前向迭代器、双向迭代器、随机访问迭代器和连续迭代器C++20,不同类别支持不同的操作迭代器的常见操作包括解引用*获取元素值、递增++移动到下一元素、比较==、!=判断是否到达同一位置更高级别的迭代器支持更多操作,如双向迭代器支持递减--,随机访问迭代器支持加减运算+、-和比较大小、迭代器失效是使用STL容器时的常见问题,当容器结构发生变化如插入、删除元素时,之前获取的迭代器可能变得无效不同容器对迭代器失效的规则不同,理解这些规则对编写正确的STL代码至关重要自定义迭代器通常通过重载必要的运算符来实现,使自定义容器能与STL算法无缝配合算法STL非修改性序列操作是不改变元素值或顺序的算法,包括查找find,find_if、计数count,count_if、比较equal,mismatch等这些算法通常用于分析数据,不会修改容器内容,适合用于const迭代器修改性序列操作会改变元素值或顺序,包括转换transform、替换replace、删除remove、重排reverse,rotate等这些算法直接修改容器内容或生成修改后的新序列,需要注意迭代器失效问题排序算法包括完全排序sort,stable_sort和部分排序partial_sort,nth_element二分查找算法binary_search,lower_bound,upper_bound要求序列已排序,提供对数时间复杂度的查找数值算法提供各种数学操作,如累加accumulate、内积inner_product等,而生成算法generate,iota则用于按规则填充序列函数对象与表达式Lambda函数对象设计与应用Lambda表达式语法函数对象仿函数是实现了operator的类的对象,可以像函数一样调用相比普通函数,Lambda表达式C++11提供了创建匿名函数对象的简洁语法,语法结构为[捕获列表]参数函数对象可以保持状态,通过成员变量存储中间结果或配置信息函数对象广泛用于STL列表-返回类型{函数体}Lambda极大简化了需要使用函数对象的场景,特别是传递简算法中作为自定义操作的回调,如排序准则、变换规则等单回调函数给算法时,使代码更加清晰简洁struct GreaterThan{//Lambda等价于上面的函数对象int threshold;auto it=find_ifnums.begin,nums.end,GreaterThanint t:thresholdt{}[threshold=10]int value{bool operatorint value const{return valuethreshold;return valuethreshold;};}};//简化版本auto it=find_ifnums.begin,nums.end,//使用方式[]intvalue{vector nums={1,9,4,12,3};return value10;auto it=find_ifnums.begin,nums.end,};GreaterThan10;捕获列表决定了Lambda可以访问的外部变量[=]表示值捕获所有变量,[]表示引用捕获所有变量,也可以指定特定变量的捕获方式C++14增加了广义捕获,允许移动捕获和表达式捕获,C++20则支持模板参数Lambda表达式实际上被编译器转换为一个匿名类的函数对象智能指针详解shared_ptr unique_ptr共享所有权,引用计数跟踪独占所有权,不可复制自定义删除器weak_ptr控制资源释放的方式观察shared_ptr,不增加引用计数shared_ptr实现共享所有权模型,多个shared_ptr可以指向同一对象,通过引用计数跟踪对象生命周期,当最后一个shared_ptr销毁或重置时释放对象shared_ptr支持安全地在容器中存储多态对象,自动处理继承关系,但需注意循环引用问题unique_ptr实现独占所有权模型,确保同一时刻只有一个智能指针管理对象unique_ptr不可复制,但可以移动,适合表示独占资源和实现PIMPL模式unique_ptr在移动语义和效率方面优于shared_ptr,当不需要共享所有权时应优先使用weak_ptr用于观察shared_ptr管理的对象而不影响其生命周期,不增加引用计数通过lock方法可以安全地获取临时shared_ptr,检查对象是否仍然存在weak_ptr主要用于解决shared_ptr循环引用问题,以及缓存、观察者模式等需要临时访问对象的场景内存管理进阶内存池设计内存池预先分配大块内存,然后按需分配小块给应用,避免频繁系统调用的开销内存池特别适合频繁创建和销毁相同大小对象的场景,如游戏中的粒子系统、网络服务器的连接对象等内存池能显著提高内存分配效率,减少内存碎片自定义分配器C++允许为容器指定自定义内存分配器,控制内存分配策略通过实现符合标准的分配器接口,可以将STL容器与特定内存管理策略结合,如使用内存池、共享内存或特定对齐要求的内存自定义分配器是优化内存密集型应用的强大工具placement new操作placement new允许在预先分配的内存位置构造对象,分离内存分配和对象构造过程这对自定义内存管理、对象池实现和内存布局控制非常有用使用placement new时需要手动调用析构函数,因为内存不会自动释放对齐与内存布局内存对齐影响数据访问效率和某些硬件功能的使用C++11引入alignof和alignas控制数据对齐,C++17的std::aligned_storage和std::aligned_alloc提供更精细的对齐控制了解结构体内存布局和填充规则对优化内存使用和提高缓存效率很重要多线程编程std::thread的使用C++11引入了标准线程库,std::thread类提供了创建和管理线程的能力线程可以执行函数、函数对象或Lambda表达式,并可以传递参数线程创建后立即开始执行,可以通过join等待完成或detach分离运行线程是实现并发的基本单位,但需要谨慎处理共享数据访问互斥量与锁互斥量mutex用于保护共享数据,确保同一时刻只有一个线程可以访问C++提供多种互斥量类型和锁包装器,如std::mutex基本互斥量,std::recursive_mutex允许同一线程多次锁定,std::lock_guard和std::unique_lock提供RAII风格的锁管理,自动处理锁的获取和释放条件变量与信号量条件变量std::condition_variable用于线程间的通知和等待,实现线程协作一个线程可以等待特定条件满足,另一个线程在满足条件时发出通知C++20引入了信号量std::counting_semaphore,提供了更简单的线程同步机制,控制同时访问资源的线程数量原子操作提供了无锁的线程同步机制,std::atomic模板支持整数、布尔值和指针的原子操作原子操作避免了互斥量的开销,适合简单的计数器和标志位等场景无锁编程通过精心设计的数据结构和算法,实现无需互斥量的线程安全操作,但通常更复杂且难以正确实现并发编程模式1生产者-消费者线程间数据传递的经典模式,通过安全队列实现2读写锁允许多线程同时读取,但写入需独占访问3线程池预创建工作线程,处理任务队列中的作业4任务窃取空闲线程从忙碌线程队列窃取任务,平衡负载生产者-消费者模式是并发编程中最常用的模式之一,一组线程生产者生成数据并放入共享缓冲区,另一组线程消费者从缓冲区取出数据处理这种模式通过解耦生产和消费过程,实现高效的并行处理实现时通常使用线程安全的队列和条件变量实现线程协作线程池是管理工作线程的有效机制,避免频繁创建和销毁线程的开销典型实现包括固定数量的工作线程和一个任务队列,线程循环从队列获取任务执行线程池适合处理大量短期任务,如网络服务器的请求处理、并行计算中的子任务等现代并发库如C++17的并行算法和C++20的协程提供了更高级的并发抽象,简化了复杂并发模式的实现这些特性允许开发者专注于业务逻辑,而不是线程管理的底层细节,同时由编译器和运行时优化执行效率异常处理机制try块监视可能抛出异常的代码throw语句抛出异常对象,中断正常流程catch块捕获并处理特定类型的异常noexcept说明符声明函数不会抛出异常C++的异常处理机制通过try-catch-throw语法实现try块包含可能抛出异常的代码,throw语句抛出异常对象,catch块捕获并处理异常当异常被抛出时,程序寻找匹配的catch块;如果找不到,异常继续向上传播这种机制将错误检测与错误处理分离,提高代码可读性自定义异常类通常继承自std::exception或其派生类,并重写what方法提供错误信息良好的异常类层次结构使异常处理更加灵活,可以根据异常具体类型采取不同处理策略,或者捕获基类处理一组相关异常异常安全性是指代码在发生异常时的行为特性C++定义了三种异常安全保证基本保证不泄露资源、保持对象在有效状态、强保证操作要么完全成功,要么回滚到操作前状态和不抛出保证承诺不抛出异常设计异常安全的代码需要利用RAII、智能指针等技术自动管理资源原则与应用RAII资源获取即初始化RAIIResource AcquisitionIs Initialization是C++的核心设计原则,将资源获取与对象初始化绑定,将资源释放与对象销毁绑定这确保了资源的自动管理,即使在异常情况下也能正确释放资源,避免资源泄漏RAII在锁管理中的应用互斥量锁是RAII应用的典型例子std::lock_guard在构造时获取锁,在析构时自动释放锁,无论正常退出还是异常发生都确保锁的释放这避免了忘记解锁导致的死锁问题,使代码更安全可靠自动化资源释放除了锁管理,RAII可应用于文件句柄、网络连接、动态内存等各种资源智能指针unique_ptr,shared_ptr是管理动态内存的RAII实现,确保内存在不再需要时自动释放,防止内存泄漏RAII设计模式示例实现RAII类型时,应确保资源在构造函数中获取,在析构函数中释放,并禁止或谨慎处理拷贝/移动语义ScopeGuard是通用的RAII模式,在析构时执行任意清理代码,适用于没有专门RAII包装的资源现代特性C++C++11/14右值引用和移动语义是C++11的重大创新,通过区分左值和右值,实现了资源的高效转移而非复制移动构造函数和移动赋值运算符接受即将销毁的对象右值的资源,避免了不必要的深拷贝这大大提高了涉及大量数据移动的操作效率,如容器重新分配、返回大对象等场景auto关键字简化了复杂类型的声明,由编译器根据初始化表达式推导变量类型这提高了代码可读性和可维护性,特别是处理迭代器、Lambda表达式等复杂类型时decltype运算符则提供了查询表达式类型的能力,与auto结合使用可以实现更灵活的类型推导范围for循环for-each提供了遍历容器和数组的简洁语法,消除了显式迭代器操作和索引管理nullptr是类型安全的空指针常量,替代了容易出错的NULL宏强类型枚举enum class解决了传统枚举的作用域污染和类型安全问题,提供了更严格的类型检查和作用域控制现代C++特性C++17/20结构化绑定C++17引入的结构化绑定允许一次性解包元组、数组和结构体的多个成员到独立变量,简化了多返回值的处理这使代码更加简洁易读,特别是处理map迭代、函数返回多个值等场景时auto[iter,success]=myMap.insert{key,value};if success{//使用iter处理新插入的元素}if/switch初始化语句C++17允许在if和switch语句中添加初始化部分,限制变量作用域,提高代码安全性这避免了临时变量污染外部作用域,同时将变量声明与使用紧密结合,增强了代码的局部性和可读性if autoit=myMap.findkey;it!=myMap.end{//使用it访问找到的元素}else{//处理未找到情况}概念ConceptsC++20引入的概念Concepts是对模板参数的约束机制,允许指定类型必须满足的要求这极大改善了模板错误信息,简化了模板编程,并支持函数重载基于概念而非SFINAE,使模板代码更加清晰和可维护协程Coroutines与模块ModulesC++20的协程支持函数暂停和恢复执行,简化了异步编程模块系统则替代了传统的头文件包含机制,提供了更好的编译隔离和更快的编译速度这些特性代表了C++语言向现代化、高效率方向的重要演进文件与操作IO文件流操作二进制文件处理C++通过流类层次结构处理输入输出操作std::ifstream用于文件读取,处理二进制文件需要使用std::ios::binary标志打开文件,并通过read和write方std::ofstream用于文件写入,std::fstream支持读写操作文件流提供了打开、关法读写原始字节二进制IO适合处理非文本数据,如图像、音频或自定义格式,但闭、读写和定位等基本操作,以及错误处理机制需要注意平台差异和字节序问题std::ifstream inputdata.txt;std::ofstream outputdata.bin,if input{std::ios::binary;std::string line;if output{while std::getlineinput,line{MyStruct data{42,
3.14,Hello};//处理每一行数据output.writereinterpret_castdata,}sizeofdata;input.close;output.close;}}格式化输入输出通过流操纵算子如std::setw,std::setprecision和格式化标志控制数据的表示方式C++还支持自定义类型的IO操作符重载,,使自定义类型能够像内置类型一样使用流操作这种统一的接口简化了IO操作,提高了代码的可读性和可维护性C++17引入了文件系统库std::filesystem,提供了平台无关的文件和目录操作这包括路径操作、文件状态查询、目录遍历、文件操作复制、移动、删除等功能,极大简化了跨平台文件管理代码的编写,替代了传统的依赖操作系统API的解决方案设计模式在中的应用C++创建型模式创建型模式关注对象的创建机制,将对象的创建与使用分离工厂模式Factory通过专门的工厂类创建对象,隐藏具体类的实例化细节;单例模式Singleton确保类只有一个实例并提供全局访问点;建造者模式Builder分步骤构建复杂对象;原型模式Prototype通过复制现有对象创建新对象结构型模式结构型模式关注类和对象的组合方式,形成更大的结构适配器模式Adapter使接口不兼容的类能一起工作;装饰器模式Decorator动态添加功能到对象;代理模式Proxy为其他对象提供占位符或访问控制;组合模式Composite将对象组合成树形结构;桥接模式Bridge将抽象与实现分离,使它们可以独立变化行为型模式行为型模式关注对象间的通信和职责分配观察者模式Observer定义对象间的一对多依赖,当一个对象状态改变时自动通知依赖者;策略模式Strategy定义一系列算法并使它们可互换;命令模式Command将请求封装为对象,支持撤销等操作;状态模式State允许对象在内部状态改变时改变行为;模板方法模式Template Method定义算法骨架,允许子类重定义特定步骤C++特性与设计模式结合C++特有的语言特性为实现设计模式提供了独特工具模板支持编译期多态,可实现策略模式;虚函数支持运行时多态,适用于工厂方法和观察者模式;多重继承和混入类Mixin提供了组合功能的灵活方式;智能指针简化了内存管理;Lambda表达式简化了回调和小型策略的实现现代C++推荐组合优于继承,使用值语义和移动语义优化性能代码优化技术性能优化原则编译期优化缓存友好设计性能优化应遵循先测量,后优化C++提供强大的编译期计算能力,现代CPU性能受内存访问模式影响原则,使用分析工具确定真正的瓶constexpr允许函数在编译期执显著,缓存友好的数据结构和算法颈过早优化可能导致代码复杂度行,减少运行时开销模板元编程能大幅提高性能这包括减少缓存增加而收益有限优化应关注算法和常量表达式可实现编译期算法、未命中、避免伪共享、使用紧凑数复杂度、内存访问模式、并行处理类型转换和条件逻辑,生成高效的据布局、利用数据局部性原理、优机会等关键因素,同时保持代码可运行时代码编译器优化选项-化内存对齐等技术,使程序更高效读性和可维护性O2,-O3也能自动执行代码优化地利用CPU缓存SIMD指令集单指令多数据SIMD指令允许同时处理多个数据元素,大幅提高计算密集型任务性能C++支持通过内联汇编、编译器内部函数或std::experimental::simd使用SIMD指令,如SSE、AVX等向量化是利用SIMD加速循环的关键技术代码调试与测试调试工具与技巧单元测试框架性能分析工具有效调试依赖于合适的工具和方法调试器如单元测试验证代码单元的正确性,C++常用的测试性能分析工具帮助识别程序的性能瓶颈采样分析GDB、LLDB、Visual StudioDebugger支持设置框架包括Google Test、Catch
2、Boost.Test等这器如Perf、VTune记录程序定期快照,识别热点断点、单步执行、变量检查等功能调试技巧包括些框架提供测试用例定义、断言机制、测试夹具函数;检测分析器如Callgrind记录每条指令,提二分查找法定位错误、条件断点捕获特定条件、内fixture、参数化测试等功能测试驱动开发供详细但开销较大的分析这些工具通常提供CPU存检查工具识别内存错误等日志和断言也是重要TDD方法先写测试再实现代码,有助于设计清晰使用、内存访问、缓存命中率等多维度分析,指导的调试辅助手段接口和可测试组件优化方向内存泄漏和越界访问是C++常见的难以调试的问题内存泄漏检测工具如Valgrind、AddressSanitizer通过跟踪内存分配和释放,识别未释放的内存这些工具能检测堆溢出、栈溢出、释放后使用等内存错误,大大减少了内存相关bug的调试时间静态分析工具如Clang StaticAnalyzer、Coverity则可以在编译时发现潜在问题跨平台开发跨平台编译与构建跨平台C++开发首先需要解决编译与构建问题CMake是广泛使用的跨平台构建系统生成器,它能为不同平台生成本地构建文件如Makefile、Visual Studio项目其他选择包括Meson、Bazel等现代构建系统包管理工具如Conan、vcpkg简化了依赖处理,进一步提高了跨平台开发效率平台相关代码隔离良好的跨平台设计应将平台相关代码与平台无关代码分离常用方法包括抽象工厂模式创建平台特定对象、策略模式封装平台差异、桥接模式分离接口与实现平台特定代码应集中在明确定义的适配层,减少平台差异对核心逻辑的影响条件编译与预处理器预处理器条件指令如#ifdef,#if defined用于包含平台特定代码常见预定义宏包括_WIN32Windows、__APPLE__macOS、__linux__Linux等虽然条件编译简单直接,但过度使用会导致代码难以维护,应尽量限制在底层平台抽象层使用可移植性最佳实践提高代码可移植性的最佳实践包括使用标准C++特性而非编译器扩展;注意整数类型大小和字节序差异;使用std::filesystem等跨平台库代替平台API;避免对特定平台假设;全面测试不同平台配置跨平台开发需要在设计初期就考虑可移植性,而非事后适配网络编程基础Socket编程模型TCP/IP协议应用Socket是网络通信的基础抽象,提供进程间通信端点可靠的连接导向协议,适合需要数据完整性的应用网络库异步IO与事件驱动简化网络编程的高级抽象库,如Boost.Asio、ZeroMQ高效处理大量并发连接的编程模型Socket编程是C++网络编程的基础,提供了与网络通信的底层接口Socket API包括创建套接字、绑定地址、监听连接、接受连接、发送和接收数据等操作C++中可以使用POSIXSocket API或平台特定API如Windows Socket,但这些API通常比较底层,需要手动处理很多细节TCP/IP是最常用的网络协议栈,TCP提供可靠的、面向连接的通信,适合需要数据完整性的应用;UDP提供不可靠的、无连接的通信,适合实时性要求高的应用C++网络编程需要理解这些协议的特性,选择合适的协议,并正确处理网络错误、超时、断连等情况现代网络应用通常采用异步IO和事件驱动模型,以高效处理大量并发连接Boost.Asio、libuv等库提供了跨平台的异步IO抽象,支持回调、Future/Promise、协程等多种异步编程模型高级网络库如ZeroMQ、gRPC、Poco提供了更高层次的抽象,简化了复杂网络应用的开发数据库交互SQL数据库连接ORM框架设计C++连接SQL数据库通常通过数据库特定的客户端库或ODBC开放数据库连接实现常用接口包括MySQL Connector/C++、对象关系映射ORM框架提供了对象与数据库表之间的映射,简化了数据库操作C++的ORM库包括ODB、SQLiteCpp、libpqPostgreSQL、ODBC API等这些API提供了连接管理、SQL语句执行、结果集处理等基本功能,但使用方式各不相同,SQLite ORM等,这些库允许通过C++对象直接操作数据库,无需手写SQL语句ORM提高了开发效率和代码可维护性,但可能代码可移植性较差引入性能开销,需要在便利性和性能之间权衡//MySQL Connector/C++示例//ODB ORM示例try{#pragma dbobjectsql::Driver*driver=get_driver_instance;class Person{std::unique_ptr conprivate:driver-connecttcp://
127.
0.
0.1:3306,user,password;#pragma dbid autocon-setSchemamydb;unsigned longid_;std::unique_ptr stmtcon-createStatement;std::string name_;std::unique_ptr resint age_;stmt-executeQuerySELECT*FROM users;public:while res-next{//getters andsettersstd::coutres-getStringnamestd::endl;};}}catch sql::SQLException e{//使用std::cerrError:e.what;database db...;}Person john{John Doe,30};db.persistjohn;typedef odb::query query;result r=db.queryquery::age20;事务处理对于保证数据库操作的原子性至关重要C++数据库接口通常提供事务控制API开始、提交、回滚,RAII模式可用于自动管理事务生命周期并发控制机制如锁定和乐观并发控制OCC用于处理多用户环境下的数据一致性问题NoSQL数据库如MongoDB、Redis提供了不同于关系数据库的数据模型和接口C++连接NoSQL数据库通常使用官方客户端库或第三方包装器,如mongo-cxx-driver、redis-plus-plus等这些库通常提供异步API,适合高并发应用场景图形界面编程C++提供多种GUI框架选择,适应不同需求和平台Qt是最流行的跨平台C++GUI框架,提供丰富的组件、工具和功能,支持桌面和移动开发wxWidgets提供本地外观的跨平台界面,使用平台原生控件ImGui是轻量级的即时模式GUI库,适合工具和游戏开发其他选择包括GTKmmLinux原生、MFCWindows原生等Qt框架的核心特性是信号槽机制,这是一种类型安全的回调系统,用于对象间通信当对象状态改变时发射信号,连接到该信号的槽函数自动执行,实现松耦合的组件交互Qt还提供了属性系统、元对象系统和丰富的控件库,简化了复杂GUI应用的开发MVC模型-视图-控制器架构是GUI应用的常用设计模式,分离数据、表现和控制逻辑在C++GUI应用中,模型管理数据和业务规则,视图负责界面显示,控制器处理用户输入和协调模型与视图这种分离提高了代码的可维护性和可测试性,特别适合复杂的数据驱动应用游戏开发基础游戏循环设计物理引擎与碰撞检测渲染管线基础游戏循环是游戏引擎的核心,负责持续更新游物理引擎模拟游戏世界中的物理行为,如重渲染管线将3D场景转换为2D图像,包括顶点处戏状态和渲染画面典型的游戏循环包括处理力、碰撞、弹性等碰撞检测是物理引擎的关理、光栅化、片段处理等阶段C++游戏开发通输入、更新游戏逻辑、渲染画面三个主要阶键部分,包括宽相broad phase快速筛选可能常使用OpenGL、DirectX或Vulkan等图形段良好的游戏循环设计需要处理可变帧率、碰撞的对象,和窄相narrow phase精确计算API,或更高级的引擎如Unreal、Unity现代固定更新间隔、渲染与逻辑分离等问题,确保碰撞点和响应C++游戏开发常用的物理引擎包渲染技术包括PBR基于物理的渲染、实时全局游戏在不同硬件上有一致的行为括Box2D2D和Bullet Physics3D光照、后处理效果等,提升游戏画面质量游戏开发中的资源管理涉及加载、缓存和释放各种资源纹理、模型、音频等高效的资源管理需要考虑加载时间、内存使用和磁盘访问,技术包括资源流式加载、LOD细节层次、资源池和缓存策略等C++的手动内存管理和RAII原则对实现健壮的资源系统特别有用嵌入式系统开发内存限制与优化实时系统编程嵌入式系统通常具有严格的内存限制,要求开发者精细控制内存使用常用技术实时系统要求在确定的时间内响应事件,分为硬实时必须满足截止时间和软实包括避免动态内存分配、使用静态内存池、减少标准库依赖、优化数据结构大小时偶尔错过截止时间可接受C++实时编程需要避免不确定性因素,如垃圾收等C++嵌入式开发通常避免异常处理和RTTI等需要额外运行时支持的特性,使集、动态内存分配和深层次递归实时操作系统RTOS如FreeRTOS、QNX提供用定制的内存分配器和编译器优化选项减少代码和数据大小了任务调度、中断处理和精确定时功能,支持C++开发硬件交互接口嵌入式C++最佳实践嵌入式C++需要直接与硬件交互,通过内存映射I/O、寄存器操作和中断处理访嵌入式C++开发的最佳实践包括使用适当的子集如MISRA C++或Embedded问外设C++提供volatile关键字标记可能被外部更改的变量,但通常需要平台特C++,避免难以预测的语言特性;采用静态分析工具检查代码质量和安全性;实定的内联汇编或内部函数进行底层操作现代C++嵌入式开发通常使用硬件抽象施严格的代码审查和测试流程;选择合适的编译器优化级别平衡性能和代码大层HAL,提供统一接口访问不同硬件平台小;使用交叉编译和硬件模拟器进行开发和测试与其他语言交互C++C++/Python混合编程JNI与Java交互WebAssembly与JavaScriptC++和Python结合是科学计算和机器学习中的常见模Java本地接口JNI允许Java代码调用C++实现的本地WebAssemblyWASM允许将C++代码编译为在浏式,利用Python的易用性和C++的性能主要集成方方法,常用于需要访问系统资源或性能关键代码的览器中运行的二进制格式,与JavaScript交互法包括Python C扩展API手动编写扩展模块、Java应用JNI提供了数据类型映射、异常处理和对Emscripten是主要的C++到WASM编译工具链,支Boost.Python简化C++类暴露、pybind11现代轻量象引用管理机制,但使用复杂且容易出错现代替代持大部分C++标准库和部分POSIX API这使得性能级工具和SWIG自动生成包装器这种混合方法通方案如JavaCPP提供了更简单的接口,减少了手动JNI密集型应用如游戏、图像处理、模拟器可以在Web常用于性能关键部分使用C++实现,然后通过Python代码编写的需要平台上以接近原生的速度运行,同时保持与脚本调用和控制JavaScript的互操作性外部函数接口FFI是语言间互操作的通用机制,允许一种语言调用另一种语言实现的函数C++作为系统级语言,通常是FFI的目标语言,通过导出C风格API避免名称修饰和ABI兼容性问题供其他语言调用设计良好的FFI接口应考虑跨语言的内存管理、错误处理、数据结构表示和线程安全性,提供简单一致的API减少使用者的负担代码维护与重构持续交付自动化构建、测试和部署流程代码审查团队评审确保代码质量和标准重构技术改进代码结构而保持外部行为代码异味识别发现需要改进的代码模式代码异味是指代码中可能表明更深层次问题的征兆,如过长函数、过大类、重复代码、过多参数等识别代码异味是重构的第一步,可以通过代码审查、静态分析工具或度量指标发现C++特有的代码异味包括资源管理不当、过度使用宏、复杂的继承层次、不必要的友元等重构是在不改变外部行为的前提下改进代码内部结构的过程常见的C++重构技术包括提取函数/类、引入RAII类、替换条件语句为多态、使用智能指针替代裸指针、应用设计模式等重构应小步进行并由自动化测试支持,确保不引入新问题代码审查是保证代码质量的关键实践,通过团队成员互相检查代码,发现潜在问题并分享知识C++代码审查应特别关注内存管理、异常安全、性能关键路径和可维护性自动化工具如静态分析器、代码格式化工具和CI系统可以辅助代码审查,处理机械性检查,使人工审查专注于更复杂的问题项目实战C++项目架构设计建立清晰的系统结构和组件关系组件化与模块化划分独立功能单元,定义清晰接口版本控制与协作管理代码变更和多人开发流程发布与部署策略规划软件交付和更新机制项目架构设计是C++项目成功的基础,良好的架构应具备高内聚低耦合、关注点分离、单一职责等特性常用的架构模式包括分层架构、微服务、领域驱动设计等C++项目架构应特别考虑性能关键路径、内存管理策略、错误处理机制和跨平台兼容性,在设计初期就解决这些关键问题组件化和模块化是管理大型C++项目复杂性的关键组件应有明确定义的职责和接口,内部实现细节对外部隐藏C++20的模块系统提供了语言级支持,改进了传统的头文件包含机制良好的依赖管理如避免循环依赖和接口设计如PIMPL模式有助于创建松耦合的系统版本控制是现代软件开发的基础实践,Git是最流行的版本控制系统C++项目协作通常采用分支策略如Git Flow、GitHub Flow管理特性开发和发布持续集成CI系统自动构建和测试代码变更,确保代码质量发布策略应考虑二进制兼容性、依赖管理、版本号管理和更新机制,使软件能够可靠地交付给用户性能分析与调优未来发展趋势C++23标准前瞻C++23计划引入更多现代化特性,包括模块改进、反射能力、协程增强、标准库扩展等这些特性将进一步简化C++开发,提高代码安全性和表达能力,同时保持对性能和效率的关注未来标准更新可能采用更频繁的发布周期,提供更快的语言演进现代C++最佳实践现代C++编程风格强调安全性、表达力和效率的平衡推荐实践包括优先使用标准库而非自定义实现;采用RAII和智能指针管理资源;利用类型推导和范围for简化代码;减少继承层次复杂度;使用值语义和移动语义优化性能;编写更具声明性的代码与新兴技术的结合C++正与多个新兴技术领域结合,包括人工智能和机器学习如TensorFlow C++API、量子计算、区块链、物联网和边缘计算等C++的高性能和硬件控制能力使其在这些计算密集型和资源受限场景中保持竞争力,同时现代C++特性也使其更易于在这些领域应用C++社区资源推荐保持C++知识更新的重要资源包括CppCon、C++Now等会议;isocpp.org官方网站;HerbSutter、Scott Meyers等专家的博客和著作;Stack Overflow和Reddit r/cpp社区;CppCast播客等积极参与社区不仅有助于学习新知识,也能贡献自己的经验和见解总结与展望4关键学习路径循序渐进的C++学习阶段10+核心概念掌握C++的基础与高级特性50+实践项目通过动手实现巩固知识∞学习可能性不断发展的语言与应用领域我们在本课程中系统学习了C++的核心概念和高级特性,从基础语法、面向对象编程到模板、STL、多线程和现代C++特性这些知识构成了成为C++专业开发者的坚实基础,但真正的掌握需要持续的实践和深入学习推荐的学习路径包括首先掌握C++核心语法和面向对象基础;然后深入STL和泛型编程;接着学习现代C++特性和最佳实践;最后专注于特定领域的C++应用,如游戏开发、系统编程或高性能计算每个阶段都应结合项目实践,将理论知识应用到实际问题中进阶学习资源包括《Effective ModernC++》、《C++Templates》等经典著作,cppreference.com等参考网站,以及GitHub上的开源项目建议实践项目包括数据结构和算法实现、小型游戏引擎、多线程应用、网络服务器等,这些项目能全面锻炼C++技能,准备好迎接职业挑战。
个人认证
优秀文档
获得点赞 0