自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(182)
  • 收藏
  • 关注

原创 C++ STL:stack、queue、priority_queue 与容器适配器

在 C++ STL 中,栈 (stack)队列 (queue)优先队列 (priority_queue)是非常常用的容器适配器,它们底层依托其他容器实现,封装了特定的数据结构操作规则。本文将详细讲解三者的概念、使用方法、底层实现、经典 OJ 题目,并深入解析容器适配器与默认底层容器deque。stack 是一种后进先出(LIFO)的容器适配器,元素只能从栈顶一端插入、删除、访问。stack 是容器适配器,不单独实现数据存储,而是封装其他容器(vector/deque/list)的接口;

2026-04-15 09:57:47 387

原创 UDP 服务端 + 客户端 全场景字节序 & 类型转换

主机发给网络 → 用htons (Host TO Network Short) 主机端口 → 网络字节序(短整型 16 位)//服务端中,绑定bind服务端进程的端口号//客户端中,把目标服务器端口serverport放入struct sockaddr_in server中;网络发给主机 → 用ntohs(网络字节序-> 主机端口(短整型 16 位)//服务器获得客户端的端口号端口一定用htonsntohsIP 字符串一定用inet_addrinet_ntoaINADDR_ANY 必须。

2026-04-13 20:17:00 243

原创 STL list

/ 1. 空构造// 2. 构造 n 个 val// 3. 拷贝构造// 4. 迭代器区间构造list =带头双向循环链表插入删除 O (1),不支持随机访问迭代器是封装类型,不是原生指针插入不失效,删除只失效当前迭代器节点 + 迭代器封装 + 反向迭代器适配器工程中用于频繁插入删除的队列、链表、任务系统。

2026-04-13 18:55:27 294

原创 C++11 可变参数模板

支持接收 0 个~任意多个模板参数的模板,就是可变参数模板。// 固定2个模板参数,无法适配更多/更少参数// 可变参数函数模板:接收任意个数、任意类型的参数template <class ...Args> // Args:模板参数包void ShowList(Args... args) {} // args:函数形参参数包接口底层原理效率适用场景push_back构造临时对象 → 拷贝 / 移动到容器内存较低传入已存在的对象原地构造对象,直接用参数构造,无临时对象更高。

2026-04-11 20:59:17 402

原创 C++ vector底层原理:从内存分配到对象销毁

结合以上所有知识点,我们可以梳理出vector从扩容到销毁的完整底层流程,这也是STL容器动态管理的核心逻辑,记牢这四步,就吃透了vector的底层:扩容时:用operator new分配一块更大的裸内存 → 用placement new将旧内存中的元素拷贝构造到新内存 → 手动析构旧内存中的元素 → 释放旧内存 → 更新三个核心指针(_start、_finish、_end_of_storage)。销毁时:调用clear()批量析构所有元素 → 用::operator delete释放整块内存。

2026-04-09 10:00:15 376

原创 C++ STL :vector

在 C++ 开发中,std::vector是使用频率最高的容器之一。它既拥有数组随机访问的高效特性,又具备动态扩容的灵活性,几乎可以替代大部分原生数组的使用场景。扩容机制、迭代器失效、深浅拷贝问题等等。本文将从 vector 的核心特性出发,依次讲解常用接口、空间增长策略、最让人头疼的迭代器失效问题,最后带你动手模拟实现一个简易 vector。vector 是 C++ STL 中的可变大小动态数组,其底层采用连续存储空间存储元素。与数组一样,支持下标 O(1) 随机访问,效率极高。

2026-04-09 09:32:02 318

原创 深入浅出 C++ string 类:从原理到实战

string是C++标准模板库(STL)中的一个类模板 basic_string的实例化。本质头文件命名空间注意:string类独立于编码处理字节。如果处理多字节字符(如UTF-8)size()或length()返回的是字节数,而不是实际字符数(这一点在多语言环境下需格外留意)。string类是C++中最常用、最重要的类之一。核心要点使用size()获取长度,capacity()获取容量。利用reserve()预分配空间,减少扩容开销。+=操作符是追加字符串最优雅的方式。通过c_str()

2026-04-01 09:54:56 362

原创 C++11 核心新特性:类的默认成员函数强化(移动语义 + default/delete)

C++11 类共 8 个默认成员函数:原 6 个 + 移动构造 + 移动赋值移动函数生成条件:未手动实现 析构 / 拷贝 / 赋值 / 移动,编译器才会自动生成default:强制生成编译器默认函数,解决手动实现后默认函数丢失的问题delete:禁用指定默认函数,替代 C++98 繁琐的私有声明写法就地初始化:类内直接给成员变量赋默认值,简化构造函数。

2026-03-30 10:46:06 385

原创 C++11 右值引用、移动语义、完美转发

可以取地址可以放在赋值号左边变量名、解引用指针、有内存的对象int a = 10;*p = 20;// a、p、*p 都是左值不能取地址不能放在赋值号左边字面量、临时表达式、函数值返回(临时对象)普通左值引用:只能引用左值const 左值引用:可引用左值 + 右值用来引用右值,支持移动语义。

2026-03-26 19:34:43 380

原创 C++11 声明新特性:auto /decltype/nullptr 详解

关键字核心作用适用场景auto自动推导变量类型简化迭代器、复杂类型、函数指针声明decltype推导表达式类型模板编程、获取中间变量类型nullptr类型安全的空指针替代 NULL,避免整型与指针类型混淆。

2026-03-26 18:40:24 177

原创 C++11 统一列表初始化+std::initializer_list

只要类有对应的构造函数,直接用{}class Datepublic:cout << "Date构造函数调用" << endl;int _month;int _day;int main()// C++98 老式写法// C++11 列表初始化// 带=也支持return 0;✅ 效果:三种写法都能正常调用构造函数,语法更统一、更直观。

2026-03-26 18:24:11 407

原创 c++:异常处理

工程中若随意抛出不同类型的异常(如 int、string、自定义类),上层捕获会极其混乱。因此,主流做法是定义继承式异常体系,所有异常继承自同一个基类。// 异常基类public:{}// 虚函数:支持多态,子类重写返回具体错误信息protected:// 错误信息int _id;// 错误码// SQL相关异常(派生类)public:{}private:// 出错的SQL语句// 缓存相关异常(派生类)public:{}// HTTP服务器相关异常(派生类)

2026-03-24 10:48:53 350

原创 c++智能指针

内存泄漏指程序分配堆内存后,因设计错误失去对该内存的控制,导致内存无法被回收和复用。它不是物理内存消失,而是 “逻辑上的内存浪费”。RAII 特性:通过对象生命周期管理资源,自动释放;指针行为重载:重载operator*和operator->,让智能指针像普通指针一样使用。shared_ptr支持自定义删除器,适配非new// 适配malloc的资源});// 适配数组});// 适配文件句柄});智能指针的核心价值:基于 RAII 思想,自动化管理堆内存,解决内存泄漏和异常安全问题;

2026-03-23 13:30:26 361

原创 C++ 单例模式:饿汉与懒汉模式

单例模式的核心是构造函数私有化 + 禁用拷贝 + 静态全局访问点,保证实例唯一性;饿汉模式简单、线程安全,但可能浪费资源,适用于轻量级实例;懒汉模式延迟加载、节省资源,需处理线程安全和内存泄漏,C++11 可通过局部静态变量简化实现;选择哪种模式取决于实例的构造开销、使用频率及程序启动性能要求。

2026-03-18 20:35:11 380

原创 C++ 设计不可被继承的类

实现不可被继承的类,C++98 依赖 “私有化构造函数” 阻断子类构造调用,需配合静态函数创建对象;C++11 优先使用final关键字,语法简洁、语义明确;final不仅可修饰类禁止继承,还可修饰虚函数禁止重写,是现代 C++ 限制继承 / 重写的首选方案;不可被继承的类核心是保护核心逻辑不被修改,而非禁止功能复用,可通过组合方式实现功能复用。通过以上方法,可精准控制类的继承权限,避免子类随意修改核心逻辑,提升代码的健壮性和可维护性。

2026-03-18 19:32:53 444 1

原创 C++ 精准控制对象的创建位置(堆 / 栈)

控制对象创建位置的核心是阻断非目标路径:仅堆创建阻断 “直接构造栈对象”,仅栈创建阻断 “堆内存分配接口”;私有化构造函数是 “限制直接创建” 的基础,=delete(C++11)是 “禁用特定函数” 的最优解;禁用拷贝 / 移动构造是避坑关键,能防止用户通过拷贝绕过创建位置的限制。通过以上方法,可精准控制 C++ 对象的创建位置,适配不同场景下的内存管理需求,提升代码的健壮性和可维护性。

2026-03-18 19:00:40 382

原创 C++设计一个不能被拷贝的特殊类

C++98 没有专门的 “禁用函数” 语法,只能通过 “访问权限 + 函数声明策略” 实现禁止拷贝。如果仅声明但不设置为 private,用户可能在类外自行定义这两个函数,导致 “禁止拷贝” 的目的失效。外部代码调用拷贝构造 / 赋值运算符时,会因 “访问私有成员” 直接编译报错;即使是类的友元函数,也无法调用(因为函数只有声明、没有定义,链接阶段会报错)。这两个函数本就不应该被调用,定义无任何实际意义;如果定义了,类的成员函数 / 友元函数可能在内部触发拷贝(比如。

2026-03-18 18:20:57 210

原创 c++中的类型转换

专门用于多态类型转换发生在运行时,而非编译期会检查转换的合法性,不合法时返回nullptr(指针转换)或抛出bad_cast异常(引用转换)仅适用于包含虚函数的类层次结构(因为需要依赖虚函数表 vtable 实现运行时类型识别 RTTI)

2026-03-16 10:37:15 339

原创 C++ stringstream 简单介绍:告别字符数组,安全高效的字符串与数据转换利器

在C语言中,如果想要将一个整形变量的数据转化为字符串格式1. 使用itoa()函数2. 使用sprintf()函数但是两个函数在转化时,都得需要先给出保存结果的空间,那空间要给多大呢,就不太好界定, 而且转化格式不匹配时,可能还会得到错误的结果甚至程序崩溃。

2026-03-13 21:09:07 443

原创 C++的IO流

C++ 通过<fstream>类名功能核心操作ifstream只读文件流(输入)从文件读取数据到程序ofstream只写文件流(输出)将程序数据写入文件fstream可读可写文件流同时支持文件的输入和输出1.2 文件操作通用步骤定义文件流对象:根据读写需求选择ifstreamofstreamfstream;打开文件:通过构造函数或open()成员函数关联磁盘文件,指定打开模式;读写数据:使用>><<运算符(文本文件)或read()write()成员函数(二进制文件);关闭文件:通过。

2026-03-13 16:39:41 361

原创 C++ 交换排序算法:从基础冒泡到高效快排

优化点解决的问题效果三数取中有序数组导致快排退化到 O (n²)稳定保持 O (nlogn)尾递归优化递归栈过深导致栈溢出 / 函数调用开销大栈深度从 O (n)→O (logn)这个版本既保留了原有的代码结构,又完成了核心优化。

2025-12-21 18:06:03 1028

原创 直接插入排序和希尔gap排序(空间复杂度 O (1))

插入排序的核心思想是:将待排序元素逐个插入到已排序序列的合适位置,逐步构建有序序列。它是一种 “原地排序”(空间复杂度 O (1)),适用于小规模数据或接近有序的数据场景。直接插入排序是基础实现,希尔排序则是其优化版(通过分组减少逆序对,提升效率)。特性直接插入排序希尔排序时间复杂度(最好)O (n)(近乎有序)O (n)(gap=1 且数组有序)时间复杂度(平均)O(n²)O (n^1.3)(经典增量)时间复杂度(最坏)O (n²)(逆序)O (n²)(增量选择不当)

2025-12-17 11:24:15 677

原创 C++ 缺省参数:从概念到实战,新手也能秒懂

在函数声明或定义时,为函数的参数指定一个默认值。当调用该函数时,如果没有给这个参数传值,编译器就会自动使用这个默认值;如果传了值,就用传入的值覆盖默认值。缺省参数的默认值只能指定一次,且通常在 “函数声明” 中指定,“函数定义” 中绝对不能重复加!// 定义时只写参数类型,不要加默认值!// 错误:定义时重复加默认值(默认参数重复定义)。缺省参数:函数参数的 “默认备胎”,没传值就用它;全缺省:所有参数都有默认值,调用可传 0~ 全部参数;半缺省:部分参数有默认值,必须从右往左连续给;

2025-12-10 16:28:23 985

原创 C++ 函数重载:从概念到编译原理

在同一个作用域下,允许定义多个同名函数,只要它们的参数列表不同(参数类型、个数、顺序)。返回值类型不同,不能作为重载的依据。函数重载的本质:同名函数,参数列表(类型 / 个数 / 顺序)不同;C++ 支持重载的核心:编译阶段的 “名字修饰”,让重载函数生成唯一符号;C 不支持的核心:无名字修饰,重载函数符号重复,链接阶段冲突;编译 vs 链接:编译是 “承诺函数存在”(符号表记录名字),链接是 “兑现地址”(绑定符号到内存地址)。

2025-12-10 11:12:00 835 1

原创 C++ 解决海量数据 TopK 问题:小根堆高效解法

利用小顶堆维护前 k 大的数,堆顶为当前最小值;遍历剩余数据,仅替换比堆顶大的元素;适配内存数据和文件数据两种场景,代码简洁且易扩展。该思路不仅适用于找前 k 大的数,稍作修改(改为大顶堆)即可解决 “找前 k 小的数” 问题,是 C++ 处理大数据场景的必备技巧。

2025-12-10 10:42:33 616

原创 c++:两种建堆方式的时间复杂度深度解析

堆是基于完全二叉树的逻辑结构,通常用vector(任意节点≥左右孩子);(任意节点≤左右孩子)。核心结论:乱序数组建堆,向下调整(O (N))远优于向上调整(O (NlogN)),工程中优先使用向下调整;代码关键child从 1 到 n-1,找parent上浮;parent从(n-2)/2到 0,找child下沉;推导本质:完全二叉树的 “节点分布特性”(底层节点多、上层节点少)决定了两种方式的复杂度差异;实战建议:静态数组批量建堆用向下调整,动态插入用向上调整(如优先队列)。

2025-12-09 20:56:46 1355

原创 C++ 组合与继承:从设计本质到实战,吃透高内聚低耦合

组合是一种 “整体 - 部分” 的关系,核心体现“has-a”(有一个)整体对象创建时,部分对象自动创建;整体对象销毁时,部分对象也必然销毁。汽车有发动机(Car has a Engine)电脑有 CPU(Computer has a CPU)人有心脏(Person has a Heart)补充:聚合(Aggregation)是 “弱组合”(空心菱形表示),比如 “球队有球员”(球员可脱离球队独立存在);

2025-12-08 21:02:54 1123

原创 C++ 继承问题:友元无法继承,静态成员仅传使用权

特性友元关系静态变量继承继承本质无继承性(特权仅针对声明类)仅继承访问权,无所有权核心规则子类需单独声明友元才能获特权子类与父类共享父类静态变量;同名隐藏实际现象父类友元不能访问子类私有成员子类没有独立的父类静态变量副本开发注意事项避免过度依赖友元,子类友元需显式声明同名静态成员需用作用域区分;避免滥用同名友元的核心是 “类给外部的特权”,而非类的成员,因此特权无法通过继承传递 —— 父类的友元永远只 “认” 父类,不认子类;

2025-12-08 11:14:39 579

原创 C++ 继承:构造析构 的细节

知识点核心规则常见坑点子类构造 / 拷贝构造构造先父后子,拷贝构造先切片父类;自定义构造必须初始化父类构造忘记在初始化列表调用父类有参构造子类析构析构先子后父,自动调用父类析构;多态场景父类析构必须设为 virtual父类析构不加 virtual 导致子类内存泄漏。

2025-12-08 10:44:59 1117

原创 C++ 继承中的 “隐藏”(重定义):父子同名成员的关系

核心定义:当子类定义了与父类同名的成员(变量 / 函数)时,无论函数的参数列表是否相同,子类的该成员都会 “隐藏” 父类的同名成员。此时在子类作用域中,直接访问该名称会优先匹配子类的成员,父类的同名成员会被 “屏蔽”。注意:隐藏是作用域层面的屏蔽,而非函数重载(重载要求同一作用域),也不等同于多态中的 “重写”(重写有严格条件)。隐藏是 C++ 继承中 “同名成员” 导致的作用域屏蔽,变量和函数都可能触发;子类同名函数会隐藏父类所有同名函数(无论参数是否一致),这是和重载的核心区别;

2025-12-08 09:30:37 392

原创 C++ 父子继承:对比 C 语言讲透继承机制

C 语言是 “面向过程” 的,核心是 “函数 + 数据”,解决问题的思路是 “步骤化”;而 C++ 的继承机制,标志着编程思维从 “过程” 转向 “对象”—— 我们不再关注 “如何一步步实现功能”,而是关注 “如何建模对象的关系和行为”。语法上:实现代码复用,减少冗余;逻辑上:清晰建模对象的层级关系;能力上:为多态性提供基础,实现灵活的扩展。对于初学者,建议先掌握public继承的基本语法,理解父类与子类的初始化顺序、成员访问权限,再结合虚函数和多态,逐步深入。

2025-12-08 09:14:48 1361

原创 中缀与后缀表达式的思考

中缀转后缀:用栈管理操作符,按优先级和括号规则入栈 / 出栈,操作数直接输出;后缀求值:用栈管理操作数,遇到操作符弹出两个数运算,结果回栈。后缀表达式的优势在于无需处理括号和优先级,仅通过线性遍历 + 栈即可完成计算,因此被广泛应用于编译器、计算器等场景。掌握这一转换逻辑,不仅能解决算法题,也能理解计算机处理表达式的底层思路。如果需要扩展功能(如支持负数、浮点数),只需在操作数处理和运算逻辑中稍作调整,核心栈操作规则保持不变。

2025-12-04 15:43:48 627

原创 C++ 2:命名空间:解决c语言命名冲突的历史问题

变量和常量函数类和结构体枚举其他命名空间(嵌套)// 变量// 常量// 函数// 结构体int age;// 类public:int main()return 0;//输出结果Version: 13 + 5 = 8将相关的代码组织在一起,形成独立的作用域避免全局命名空间污染通过嵌套命名空间实现更精细的代码组织通过别名简化长命名空间的使用在实际开发中,合理使用命名空间可以大大提高代码的可读性和可维护性,尤其是在大型项目中。

2025-11-19 11:15:47 367

原创 c++ 1:域的概念:类,命名空间,全局,局部域 以及::域作用限定符

域(Scope)指的是程序中某个实体(如变量、函数、类)能够被访问的范围。一个实体只能在其定义的域内被直接访问,超出该域则无法直接访问(除非通过特定方式,如作用域限定符)。避免命名冲突:不同域中可以定义同名的实体。控制实体的生命周期:局部域的变量在离开域时会被销毁,而全局域的变量则在程序结束时才被销毁。本文详细介绍了 C++ 中的四种常见域:全局域、局部域、类域和命名空间域,并讲解了作用域限定符的使用方法。避免命名冲突,使代码结构更清晰。控制实体的可见性和生命周期,提高程序的安全性和可维护性。

2025-11-19 10:10:22 650

原创 c语言19:memset 与 memcpy 详解

可能会导致数据丢失或损坏。

2025-11-12 10:13:58 922

原创 c语言18:结构体位段联合体

语法格式(3 种常用形式)// 1. 普通命名结构体(可多次定义变量)// 字符串:姓名(基础类型)int age;// 整型:年龄(基础类型)// 浮点型:成绩(基础类型)struct Date // 嵌套结构体(成员为复杂类型)int year;int month;int day;} birthday;// 生日// 2. 匿名结构体(无结构体名,仅能定义一次变量)structint x;// x坐标int y;// y坐标} point;

2025-11-12 09:30:36 1036

原创 C 语言17:位操作符 & | ^:从二进制编码到大小端

(异或)凭借自反性和可逆性,在无临时变量交换、加密、差异检测中不可替代;大端与小端是内存存储的字节顺序差异,不影响位操作的逻辑结果,但在跨平台数据交互中需显式处理;位操作的高效性(直接操作硬件寄存器级别的二进制位)使其成为底层开发(嵌入式、驱动)的必备工具。掌握位操作符,不仅能写出更高效的代码,更能让你看透数据在计算机中的本质形态 —— 二进制的世界,逻辑即力量。

2025-11-11 19:43:51 1053

原创 c语言16:结构体对齐,从原理到大小计算

对齐目的:提升 CPU 访问效率,避免硬件异常;3 条规则:成员偏移量对齐自身对齐数、总大小对齐最大成员对齐数、嵌套结构体按内部最大对齐数对齐;优化技巧:按 “对齐数从小到大” 排列成员,减少填充;灵活调整:用修改对齐数,适应不同场景;验证工具offsetof宏可查看成员偏移量,辅助调试。结构体对齐是 C 语言中 “底层细节决定成败” 的典型案例,理解它不仅能帮你写出更高效的代码,更能加深对计算机内存模型的认知。实际开发中,建议结合sizeof和offsetof验证对齐结果,避免想当然的错误。

2025-11-11 18:46:25 676

原创 c语言15:深入理解 C 语言中的数组指针、函数指针

数组指针是二维数组的 “最佳拍档”,通过行级操作简化二维数据管理;函数指针是 “逻辑动态切换” 的核心,让代码更灵活(如回调、状态机);typedef 则是 “复杂类型的简化器”,通过别名提升可读性和可维护性。掌握这些概念,不仅能读懂复杂的 C 代码,更能写出高效、清晰的底层程序。建议结合实例多动手练习 —— 指针的魅力,往往在实践中才能真正体会。

2025-11-11 14:33:56 667

原创 c语言14:字符指针

字符指针既可以指向单个字符,也可以指向字符串常量的首地址。字符串常量存储在只读数据区,相同的常量字符串可能被编译器优化为 “共享内存”。字符数组是 “存储字符串内容的内存块”,而字符指针是 “指向字符串地址的工具”—— 二者在内存分配、比较逻辑上有本质区别。掌握字符指针,不仅能更高效地操作字符串,也是理解 C 语言内存模型的关键一步。

2025-10-19 22:22:45 976

javaweb的gms代码

javaweb的gms代码

2024-01-15

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除