c++
文章平均质量分 83
深入学习c++,从基础到stl
June`
难走的路从来都不拥挤
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
C++11(五):类型转换全解析
C++类型转换机制解析 C++作为强类型语言,提供了比C语言更规范的类型转换机制。C语言只有隐式和显式两种转换方式,存在可视性差、错误难追踪的问题。C++引入四种强制类型转换操作符: static_cast:用于相近类型的转换 reinterpret_cast:处理不相近类型的强制转换 const_cast:去除const属性 dynamic_cast:用于多态类型的安全向下转型 dynamic_cast通过虚表识别实际类型,仅适用于含虚函数的类。此外,C++还通过typeid运算符支持运行时类型识别(RT原创 2025-12-10 17:09:57 · 791 阅读 · 0 评论 -
C++11(四):特殊类与单例模式设计精要
本文介绍了C++中特殊类的设计方法及单例模式实现。主要内容包括:1)只能在堆/栈上创建对象的实现方式,通过禁用构造/拷贝构造并提供静态创建接口;2)不可拷贝类通过禁用拷贝构造和赋值运算符实现;3)不可继承类的两种实现方式(C++98私有构造和C++11 final关键字)。重点讲解了单例模式的两种实现:懒汉模式(使用时创建,需处理线程安全)和饿汉模式(启动时创建,无线程安全问题),分析了各自的优缺点。其中懒汉模式通过双检查锁机制解决线程安全问题,饿汉模式则利用静态成员变量在程序启动时初始化的特性。原创 2025-12-10 14:06:17 · 917 阅读 · 0 评论 -
C++11新特性全面解析(三):智能指针与死锁
本文系统介绍了C++智能指针的核心概念与技术要点。首先阐述了智能指针的必要性,通过RAII机制解决资源管理问题。重点分析了三种智能指针实现方案:auto_ptr(管理权转移)、unique_ptr(禁用拷贝)和shared_ptr(引用计数),并详细讨论了shared_ptr的线程安全问题及循环引用缺陷(通过weak_ptr解决)。文章还探讨了死锁问题与RAII锁管理机制(lock_guard/unique_lock),最后总结了内存泄漏的危害及检测方法。全文从原理到实践,完整呈现了C++资源管理的核心技术原创 2025-12-09 22:32:00 · 814 阅读 · 0 评论 -
C++11新特性全面解析(二):线程库+异常体系
本文摘要:本文系统介绍了C++11中的线程库和异常处理机制。线程库部分详细讲解了thread类的使用、线程函数参数传递、原子操作库(atomic)、互斥锁(mutex)和条件变量的应用。异常处理部分对比了C语言传统错误处理方式的缺陷,阐述了C++异常的概念、使用方法和安全规范,包括异常抛出与匹配规则、自定义异常体系设计等。文章通过代码示例展示了多线程编程中常见的竞争条件和资源管理问题,以及异常处理的最佳实践。最后分析了异常机制的优缺点,指出虽然存在执行流混乱等问题,但在现代编程中仍利大于弊,是错误处理的重要原创 2025-12-04 22:32:41 · 989 阅读 · 0 评论 -
C++11新特性全面解析(一)
C++11新特性摘要 C++11标准带来了140多项新特性,主要包括: 列表初始化:统一了内置类型和自定义类型的初始化方式,支持更简洁的初始化语法。 类型推导:auto和decltype关键字简化了复杂类型的声明。 右值引用:引入移动语义,通过移动构造和移动赋值减少不必要的拷贝,提升性能。 智能指针:unique_ptr、shared_ptr等帮助管理内存资源。 lambda表达式:提供匿名函数的简洁写法,支持闭包特性。 容器增强:新增array、forward_list等容器,改进unordered系列容原创 2025-12-03 12:08:10 · 792 阅读 · 0 评论 -
C++哈希表:unordered系列容器详解
C++中的unordered系列容器(unordered_map/unordered_set)采用哈希表实现,相比红黑树结构的map/set具有O(1)的查询效率,但元素无序。二者功能相似但底层实现不同:红黑树保持有序(logN时间复杂度),哈希表提供更快访问(O(1)平均复杂度)。unordered容器支持基本操作如insert/erase/[]访问,但迭代器为单向。适用于需要快速查找但对元素顺序无要求的场景,与有序容器形成互补选择。原创 2025-05-31 17:49:31 · 718 阅读 · 0 评论 -
STL的map和set(关联式容器深度解析)
本文介绍了C++中的关联式容器map、set及其多键值版本multimap、multiset。关联式容器通过键(key)存储元素,底层使用红黑树实现,保持元素有序性。重点讲解了set(存储唯一值)、map(存储键值对)的构造方法、插入删除操作,以及map特有的[]运算符实现原理。对比了set/map与multiset/multimap的区别,指出后者允许键重复但不支持[]操作。文章还简要提及了底层红黑树结构,强调关联式容器在查找效率(O(logn))和有序性方面的优势。原创 2025-05-25 20:00:22 · 740 阅读 · 0 评论 -
c++之多态(揭秘多态:面向对象编程的核心魅力)
本文系统讲解了面向对象编程中的多态概念及其实现机制。主要内容包括:1.多态的概念与定义("一个接口,多种实现");2.多态的实现条件(基类指针/引用调用+虚函数重写);3.虚函数表的工作原理(vptr指向虚函数地址数组);4.继承关系中的虚函数表现(单继承和多继承差异);5.抽象类与接口继承(纯虚函数强制派生类实现);6.多态相关面试问题解析(内联函数、静态函数限制等)。文章通过售票系统等实例,详细阐述了多态在编译期和运行期的绑定机制,以及虚函数表在动态绑定中的关键作用。原创 2025-05-24 13:06:18 · 891 阅读 · 0 评论 -
c++之继承(深入解析C++继承机制与代码复用技巧)
本节主要探讨了面向对象编程中的继承机制及其相关概念。首先介绍了继承的基本定义,即允许派生类复用基类的特性并扩展功能,从而减少代码冗余。接着详细讲解了基类与派生类之间的对象赋值转换、作用域规则、派生类的默认成员函数、继承与友元及静态成员的关系。特别强调了复杂的菱形继承及其带来的数据冗余和二义性问题,并提出了通过虚继承来解决这些问题的方法。最后,对比了继承与组合的优缺点,建议在实际开发中优先使用组合以降低类之间的耦合度,提高代码的可维护性。本节还通过学生管理系统的例子,展示了如何通过继承来优化类设计,减少重复代原创 2025-05-23 19:14:41 · 1390 阅读 · 0 评论 -
C++之模板进阶(探索C++模板:非类型参数与特化技巧)
本节主要介绍了C++模板编程中的几个关键概念:非类型模板参数、类模板的特化、模板特化的应用(如类型萃取)以及模板的分离编译。非类型模板参数允许使用常量作为模板参数,适用于需要固定大小的场景,如静态数组。类模板的特化分为全特化和偏特化,全特化针对特定类型提供特殊实现,而偏特化则对模板参数进行进一步限制。模板的分离编译问题指出,模板的声明和定义通常需要放在同一文件中,以避免链接错误。模板编程虽然提高了代码的复用性和灵活性,但也可能导致代码膨胀和编译时间增加。原创 2025-05-21 23:13:20 · 1424 阅读 · 0 评论 -
STL之priority_queue(揭秘C++优先队列:高效管理数据优先级)
优先队列(priority_queue)是一种容器适配器,遵循严格弱序原则,确保队列顶部始终为最大元素,类似于堆结构。它通过封装底层容器(如vector或deque)实现,支持插入和删除操作,并自动维护堆性质。优先队列默认使用less仿函数实现大堆,但可通过greater仿函数改为小堆。仿函数通过重载operator()实现类对象像函数一样调用。优先队列不支持迭代器遍历,但底层容器支持。其核心功能包括top()返回堆顶元素和pop()删除堆顶元素,适用于需要高效维护元素优先级的场景。原创 2025-05-21 21:15:08 · 1044 阅读 · 0 评论 -
STL之stack&&queue
1.栈是没有迭代器的,因为栈的特性是先进后出,不能随便访问,所以不支持迭代器2.如何遍历?先判断为不为空,不为就取栈顶的数据,取完之后pop就行3.为什么没有析构函数?因为它底层是别的容器,当stack出了作用域自动销毁时会调底层容器的析构函数1.队列是一种容器适配器,专门用于在FIFO(先进先出)中操作,其中从容器的一段插入元素,另一端提取元素2.队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素,元素从队尾入队列,从对头出队列。原创 2025-05-06 21:30:36 · 1203 阅读 · 0 评论 -
STL之list容器
1.list的底层是双向链表结构,双向链表中的每个元素在互不相关的独立结点中,在结点中通过指针指向前一个元素和后一个元素2.list是可以在常数范围内在任意位置的插入和删除的序列式容器,并且该容器可以前后双向迭代3.vector的优点:支持随机访问,间接的就支持了排序/二分查找/堆排序等缺点:1.头部和中部的插入效率低,需要挪动数据2.插入数据空间不够需要增容,增容需要开新空间,拷贝数据,释放旧空间list的优点:没有增容代价,且任意位置插入都是0(1);原创 2025-05-03 12:25:01 · 1572 阅读 · 0 评论 -
STL之vector容器
1.vector是可变大小数组的容器2.像数组一样,采用连续的空间存储,也就意味着可以通过下标去访问,但它的大小可以动态改变3.每次的插入都要开空间吗?开空间就要意味着先开临时空间,然后在拷贝旧的到新的上面,在释放原来的,就时间而言,这是一个相对代价很高的任务;显然这是不行的,vector的分配策略:会分配一些而外的空间以适应可能的增长,例如我们平时说的以1.5或者2倍的方式增容,不同的库选择不同的策略权衡空间的使用和重新分配,以至于在插入一个元素时能在常数时间内插入;原创 2025-05-02 13:41:05 · 1359 阅读 · 0 评论 -
STL之string容器
c_str():返回c格式的字符串 (在string类中是以size表示有效大小,c风格是以\0表示结束,返回c格式的字符串是在末尾加\0,而string在处理字符串是没有\0结尾表示结束,而是用size)在c语言中,字符串以"\0"结尾的一些字符的集合,并且提供了一系列的str函数,但有时候可能会越界访问,且库函数是与字符串分离的,不太符合OOP的思想,为了方便管理,c++封装了一个类。size():返回字符串的有效长度(一般用这个,length比较早期,size是与其他容器统一)原创 2025-05-01 12:55:50 · 1075 阅读 · 0 评论 -
c++之类与对象(third)
构造函数赋值:在创建对象时,编译器会自动调用构造函数进行赋值,之前简单来说叫初始化,但这里不能叫做初始化,因为初始化只能初始化一次,在构造函数体内可以重复赋值,所以出现了初始化列表。初始化列表:以一个:(冒号)开始,接着是以,(逗号)分隔的数据成员列表,每个”成员变量“后面跟一个放在括号中的初始值或表达式注意:1.每个成员变量在初始化列表中只能出现一次(对应初始化只能初始化一次)2.类中包含以下成员,必须放在初始化列表位置进行初始化:引用成员变量const成员变量。原创 2025-02-18 20:57:27 · 430 阅读 · 0 评论 -
c++之类与对象(second)
这样写就会有问题,问题在于test函数的参数是const Date&d,d所指向的内容是不可以修改的,但是在d里面调用了Printf,参数是隐含的this指针,Date const*this,这个是可以修改this所指向的内容,这说明权限放大了,要加const去修饰this指针,也就是void Print()const。在某些情况下,如果你不想直接暴露对象的真实地址,可以返回NULL,或者获取对象地址需要进行额外的控制和处理,通过&操作符重载,可以实现自定义的逻辑,而不是简单的返回对象的真实地址。原创 2025-02-18 14:57:19 · 1732 阅读 · 0 评论 -
c++之类和对象(first)
/类体:由成员变量和成员函数组成//注意有分号,类似于一条语句class为关键字,classname为类的名字,{}为类的主体,定义完后有分号;类中的元素叫做成员,类中的数据称为成员变量或者类的属性,函数称为成员函数或者类的方法1.声明和定义都在类体内注意:如果成员函数在类中定义,可能会被当初内联函数处理2.声明放在.h文件中,定义放在.cpp文件中(这种更推荐,更符合工程的思想)但定义时要声明是在哪个类中的。原创 2025-02-17 21:53:15 · 2051 阅读 · 0 评论 -
c++之内联函数
内联函数可以提高效率,但代码很长或者有循环/递归都不适用,只适合短的代码,比如交换两个值的函数?并且加了inline是否会在相应的位置展开?取决于编译器?inline只是给编译器一个建议并不是一定会展开。内联函数不建议定义和声明分离,分离会导致链接错误,因为inline被展开之后就没有函数地址了,这样就链接时就无法找到函数。原创 2025-02-17 12:13:27 · 242 阅读 · 0 评论 -
c++之引用
引用可以提高传参时的效率,避免创建临时空间,效率高。但实际使用场景得谨慎引用的底层逻辑是使用指针实现。原创 2025-02-16 21:40:19 · 1709 阅读 · 0 评论 -
c++之缺省参数
注意:1.半缺省值参数必须从右向左依次并且连续给出,不能间隔给,也就是可以给cb,不能c a。2.缺省参数不能在函数的声明和定义中同时出现(一不一样都不能同时出现)在声明或者定义时给参数一个默认值,如果调用参数时没有实参,则用缺省值(默认值);注意:传参如果像下面这样就会报错,不允许前面的不传,后面又传。1.全缺省参数:顾名思义就是全部参数都有缺省值。当传参只传一个时,a就用实参,bc用缺省值。顾名思义就是给一半(没有给全)的缺省值。当都不传参时,就都用缺省值。当传全部时,都用实参。原创 2025-02-12 19:04:03 · 238 阅读 · 0 评论 -
c++之函数重载
3为函数名的字母个数,ii为两个类型int int,那么在连接时就可以辨认出是哪个函数,例如add(int,int)就会找到<_Z3addii>,如果是add(char,char)就会找到<_Z3addcc>,windows也是同样的道理,只是命名风格不一样,那么通过这样看,如果是返回类型不一样是不能构成函数名重载的,只要参数不同就可以构成函数名重载,参数的个数,类型或者顺序不同。是一个固定的前缀,它是修饰后的名字起始标识,用于告知链接器这是一个经过 C++ 名字修饰的符号,编译器和链接器看到。原创 2025-02-12 20:40:42 · 558 阅读 · 0 评论 -
C++之auto
也就是说auto相当于一个类型声明时占位符,编译器会在编译期间将auto替换为变量的实际类型。在早期的c语言和c++auto仅仅是一个自动存储器的局部变量,也就是生命周期出了代码块就没了。实际编译器只对第一个类型推导,然后在用推导出来的类型定义其他变量,所以c和d那条编译不过。但c++11中auto是一个全新的含义:自动推导类型,编译器会在编译时期推导。这样是编译不过去的,必须要auto b=a;auto不能作为形参类型,编译器无法对a的实际类型推导。两个一样,没有区别,b和c的类型都是int*原创 2025-02-17 14:28:13 · 340 阅读 · 0 评论 -
c++之范围for
对于以前要遍历一个数组,需要程序员自己书写数组的范围(sizeof)因此c++中引入范围for,避免因为范围书写错误而导致程序有意想不到的结果。原创 2025-02-17 14:45:01 · 422 阅读 · 0 评论 -
c++入门之命名空间
命名空间:在c/c++中,有很多的变量名,函数或者类的名称存在于全局作用域中,为了避免冲突和更好的管理命名,使用命名空间能够对这些标识符本地化(也就是只有在这个命名空间的域下才可以使用)以避免命名冲突和名字污染。一个命名空间就相当于定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。在c++中使用cout输出,cin输入,并且使用<<(可以自动推导类型不用%d等)所以一般大型项目为了避免命名冲突会std::cout<<a<<endl;2.使用using把命名空间里的某部分内容展开。原创 2025-02-11 21:54:01 · 493 阅读 · 0 评论
分享