- 博客(81)
- 资源 (19)
- 收藏
- 关注
原创 C++之前向声明
简单说,就是在使用一个类型前,先告诉编译器这个名字是个类型。举个生活中的例子:假设你要为你的朋友User创建一个订单Order。// 在 Order.h 文件中class User;// 👋 前向声明:告诉编译器 "User" 是一个类private:// 我只需要知道 User 是个类型,就可以定义指向它的指针public:在这里,Order类包含一个User*指针。编译器为了编译Order类,只需要知道User是一个类型即可,而不需要知道User里面有什么成员(比如用户名、密码等)。
2025-06-11 16:20:47
456
原创 C++容器之std::set和std::unordered_set
需要注意的一点,std::set和std::unordered_set是不能(通过迭代器等)修改元素的。本质上可以认为std::set内的元素不可以修改,但std::map可以修改元素,这就是std::map更能够广泛使用的原因。关于std::set的必要性。在实际使用中,std::map比std::set的存在感高很多,但是,我还是计划使用很大的篇幅说明std::set的用法,这能在很大程度上帮助理解std::map。另,std::set也可以修改元素的属性,要删除旧的后,添加新的。
2025-06-05 14:37:59
311
原创 C++容器迭代器
+r返回值为表达值执行后的r的引用,r++返回值为表达值执行前的r的拷贝。另外,还有三个容器:std::stack、std::queue和std::priority_queue是不支持迭代器的(表面上)。a>b、a>=b、a<b和a<=b,这四个表达式的返回值类型为bool。关于迭代器,需要特别注意的一点是,迭代器并不是容器中的属性(这种是把迭代器当成了索引属性理解)。迭代器也分类的,最基本通常称为基本迭代器,英文为LegacyIterator。上面展示了迭代器的简单用法,但是迭代器的类型却不一样。
2025-05-27 08:53:16
339
原创 C++不加锁的异步编程
朋友,想象一下这个场景:你在餐厅点了一份需要20分钟才能做好的复杂菜品。你有两个选择:坐在那里盯着厨房门口,等待20分钟(同步等待)服务员给了你个取餐码,菜品好了会通知你,同时你可以刷刷手机或聊聊天(异步等待)显然,第二种方式更高效,对吧?在C++编程中,future和promise就像是这个"取餐码+通知"系统,让你的程序能够优雅地处理异步任务。它们是C++11引入的现代并发编程工具,比传统的线程、互斥锁和条件变量更加简单易用。现在,你已经了解了C++11中future和promise的基本用法。
2025-05-23 10:20:17
759
原创 C++11多线程指南
想象一下,你正在厨房做饭。如果你是单线程工作,那就只能先切菜,切完再炒菜,炒完再煮汤...一项一项按顺序来。但现实中的你肯定是多线程操作啊:锅里炒着菜,同时旁边的电饭煲在煮饭,热水壶在烧水,也许你还能同时看看手机...这就是多线程的威力!在程序世界里,多线程就像多了几个"分身",可以同时处理不同的任务,充分利用多核CPU的性能,让程序跑得飞快。特别是现在谁的电脑不是多核啊,不用多线程简直是浪费资源!
2025-05-22 09:11:35
514
原创 C++基于条件变量的线程同步
条件变量就像多线程世界里的"微信群通知":让线程之间能够高效协调工作,不必浪费CPU资源去傻等。关键知识点回顾:条件变量用于线程间的等待/通知机制必须与互斥锁配合使用使用 wait() 等待条件满足使用 notify_one()/notify_all() 通知等待的线程总是在循环中检查条件,防止假唤醒掌握了条件变量,你的C++多线程技能就上了一个台阶!再也不用担心线程间如何优雅地协作啦。
2025-05-21 16:47:20
497
原创 C++11关键字thread_local
前几天一个 C++ 初学者求助我:"我写的多线程程序结果总是错的,找不到错误原因?这段代码有什么问题?问题大了去了!多个线程同时读写同一个变量counter,没有任何保护措施,必然导致!他挠挠头问:"啊?这是什么意思?要怎么解决?加锁吗?我说:"加锁当然可以,但是今天我要教你一招更酷的方式 ——!
2025-05-18 11:40:59
604
原创 Git 常用命令
分支的合并策略、变基、快进合并、压缩提交(squash)等。这些不但影响提交记录的整洁度,也会直接关系到协作开发时的效率和出错率。当你当前分支落后于 feature 分支时,Git 不需要创建合并提交,而是直接“快进”。把 feature/login 分支的提交历史移到 main 的最后一个提交之后。结果:创建一个新的“合并提交”(merge commit)把一个分支“平移”到另一个分支上。把 feature 分支的一堆提交压成一个提交。提交代码(将暂存区的内容提交到本地仓库)
2025-05-17 15:44:27
892
原创 C++的std::call_once
是C++标准库提供的一个实用程序,用于精确执行一个函数一次,即使从多个线程并发调用。它对于初始化单例、设置共享资源或配置线程本地数据等场景特别有用。与std::mutex或双重检查锁定等替代方案相比,的关键优势在于其简单性和保证的正确性。
2025-05-08 08:45:06
274
原创 带你吃透C++互斥锁
例如,在一个多线程的数据库查询系统中,大量线程可能同时读取数据库中的数据,只有少数线程会进行数据更新操作,使用读写锁可以让多个读线程同时获取读锁,并行地读取数据,而写线程在进行更新操作时获取写锁,独占资源,保证数据的一致性,同时提高了系统的并发处理能力。例如,在一个复杂的数据结构中,如果对每个数据元素都使用一把单独的锁,虽然提高了并发性,但在多线程访问时,可能会出现线程 A 持有元素 1 的锁并等待元素 2 的锁,而线程 B 持有元素 2 的锁并等待元素 1 的锁的死锁情况。
2025-05-06 08:48:46
968
原创 C++数组和指针到底有什么区别
他看着草稿纸上的代码,脑海中闪过无数知识点,却怎么也拼不出完整的答案:。指针:是一个单独的变量,存储某个内存地址,类似 “车票” 指向火车的某节车厢。陷阱本质:函数参数中的数组会 “衰减” 为指针,导致无法通过sizeof获取原始长度。数组:包含元素类型和长度信息(即 “户口本”),是 “有身份的整体”。本质:数组中每个元素是指针,指向独立内存(可能不连续)。指针:只有地址信息(即 “门牌号”),无法得知指向的数据类型或长度。本质:数组的数组,内存连续存储。错误代码标注:。
2025-04-28 10:02:28
354
原创 std::bit_cast位级别类型转换
场景优势浮点数与整数互转(比如fast inverse sqrt)零开销、安全处理二进制协议(网络字节流)方便直接映射文件解析(比如BMP头结构体解析)避免手动解析底层优化(比如SIMD数据重组)不破坏类型安全任何需要位级别拷贝且保持行为良好的地方,都是你的好帮手。
2025-04-27 08:45:57
513
原创 std::invoke处理模板重载函数
如果非模板函数与参数类型完全匹配,则优先选择非模板函数(即使模板函数也能匹配)。:直接返回可调用对象执行后的结果(如果是成员变量指针,则返回成员变量的值)。的机制与普通函数重载类似,但需要结合模板的实例化规则和重载决议规则。:可调用对象的类型(函数、成员函数指针、Lambda 等)。:传递给可调用对象的参数列表。、Lambda 表达式等):显式特化的模板函数(如。)会优先于通用模板实例。
2025-04-26 08:31:40
249
原创 C语言结构体和union内存对齐
在C语言的世界里,结构体(struct)和联合体(union)的内存布局一直是困扰许多开发者的难题。当我们定义一个结构体时,编译器会按照特定的规则为每个成员分配内存空间,这些规则被称为内存对齐。看似简单的内存分配背后,隐藏着计算机体系结构的深层逻辑——从CPU缓存的工作机制到不同硬件平台的访问约束,内存对齐直接影响着程序的性能、可移植性甚至正确性。1. 硬件访问效率的底层需求 现代CPU并非逐字节读取内存,而是以字长(如32位机的4字节、64位机的8字节)为单位批量读取。当数据存储在未对齐的地址时,CPU
2025-04-24 08:43:07
706
原创 无锁编程的秘密与实战
无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization),实现非阻塞同步的方案称为“无锁编程算法”。为什么要非阻塞同步,使用lock实现线程同步有非常多缺点:产生竞争时,线程被阻塞等待,无法做到线程实时响应dead locklive lock优先级反转使用不当,造成性能下降假设在不使用 lock 的情况下,实现变量同步,那就会避免非常多问题。
2025-04-23 14:01:20
770
原创 POSIX多线程,解锁高性能编程
线程,作为进程内的执行单元,可以理解为进程这个大舞台上的一个个小舞者,各自有着独立的舞步(执行路径),却又共享着舞台的资源(进程资源)。与进程相比,线程更加轻量级。进程是系统进行资源分配和调度的基本单位,拥有独立的地址空间、内存、文件描述符等资源 ,进程间的切换开销较大。而线程则是共享所属进程的资源,它们之间的切换开销相对较小,就像在同一个舞台上不同舞者之间的快速换位,无需重新搭建整个舞台。线程的这些特点,使得多线程编程在提升程序执行效率上有着独特的优势。
2025-04-21 14:35:02
689
原创 C++问题,忘记为类添加拷贝构造函数和赋值运算符重载
C++ 的资源管理能力强大,但也意味着你得为每个对象的复制、赋值负责。在没有定义拷贝构造和赋值运算符的情况下,编译器的默认行为可能完全不符合你的预期。一旦类中涉及指针、文件、网络资源等,就必须认真对待这两个函数的设计。别等程序崩溃时才回过头发现:“原来我复制了一个对象,却没有复制它真正拥有的资源。
2025-04-19 16:02:41
770
原创 花括号大法,C++所有初始化技巧
好了,C++的初始化大菜已经上齐了!回顾一下我们的"菜单":int a = 10;int a(10);3、 花括号初始化大家族:int a{10};int a{};如果你是 C++ 新手,我建议从花括号初始化开始习惯,它最安全也最通用。等你熟悉了这些初始化方式的优缺点后,再根据具体场景选择最合适的那一个。记住:好的初始化习惯能让你少掉很多头发!希望这篇文章能给你带来"啊哈"的时刻,让你以后看 C++ 代码时能一眼看穿各种初始化魔法!
2025-04-18 11:34:07
877
原创 C++使用STL容器迭代器失效情况
容器内容发生变化后,原先获取的迭代器就可能变得不可用或行为未定义。失效的迭代器表面看起来还可以使用,但实际上:它可能指向已经释放的内存;它可能不再指向当前容器的合法位置;它可能让你的程序在运行时崩溃,甚至逻辑错误却难以察觉。迭代器是 C++ STL 的核心设计之一,也是构建现代 C++ 编程风格的重要组成部分。但它不像下标访问那么“直接”,更像是一把双刃剑:用得好,能写出灵活高效的代码;用得不好,可能会引入极难排查的隐患。不要因为 STL 给你提供了“操作便利”,就忘了它背后的“结构复杂”。
2025-04-18 11:29:10
565
原创 C++静态变量多线程中的未定义行为
静态变量不是不能用,但它是一种需要特别小心的“状态工具”。尤其在多线程程序中,它不再只是一个“懒惰的单例”,而是一个随时可能出问题的“全局开关”。
2025-04-16 15:05:02
801
原创 C语言static的三种超能力
记忆力:static 局部变量记住调用间的状态隐身术:static 全局变量/函数隐藏实现细节共享精神:static 在"类"中用于共享数据。
2025-04-14 09:16:10
579
原创 Linux 进程终止详解
在操作系统中,是程序运行的基本单位。当一个进程完成了它的任务,或由于某些错误被中止时,它就会。进程的终止不仅代表执行的结束,更涉及到资源的回收与系统状态的更新。
2025-04-13 09:34:36
437
原创 僵尸进程与孤儿进程
当一个子进程结束执行后,它会将终止状态(如退出码、使用的 CPU 时间等)保留在系统进程表中,供父进程查询。如果父进程没有调用wait()或waitpid()来回收子进程的资源,那么子进程的这部分信息会一直保留,这时它就变成了僵尸进程。虽然僵尸进程不再执行任何代码,但它仍占据系统资源(尤其是进程表项),并可能随着时间累积,最终导致系统无法创建新进程。
2025-04-10 09:02:13
316
原创 Linux 守护进程浅析
守护进程是脱离了用户交互界面的后台服务程序。它的典型特征包括:在后台运行,不与终端交互;没有控制终端(即tty通常在系统启动时运行,持续存在;提供某种服务(如网络、文件监听、定时任务等)。你可以通过ps -ef或top等命令查看正在运行的守护进程,常常它们的父进程是init(或 systemd,进程号为 1)。
2025-04-09 10:42:51
734
原创 Linux进程间通信详解
IPC机制速度通信方式同步性复杂度场景管道中字节流否低父子进程,简单通信消息队列中消息结构是中任务调度,解耦系统共享内存高共享内存否高大量数据交换信号量高控制机制是高临界区、同步控制。
2025-04-08 09:30:33
291
原创 C++浅谈转型操作符
这些操作符各自针对不同的转换需求,提供了更严格的类型检查和清晰的语义表达,迫使开发者在进行转换时必须明确意图,避免了隐式转换可能带来的安全隐患和混淆问题。风格的转换语法没有明确的标签来指示转换的类型,仅仅依靠圆括号包装目标类型,使得代码中转换操作不易被识别。无论是数值转换、继承关系转换,还是底层位转换和常量转换,都能通过不同的操作符表达出来,避免了任何类型都能互相转换的糟糕现象。代码时,只要存在类型转换的可能,就应显式地使用相应的转型操作符,而非依赖于隐式转换或传统的。为了解决旧式转换造成的问题,C++
2025-04-05 09:12:36
278
原创 C指针类型,8个例子讲明白
这是一个整型的二级指针,用于存放一个内存的地址,该地址对应的内存中存放了另一个整型变量的地址。假定(*va[3])是X,外面是 int (X)(int),所以指针是指向函数的。这是一个数组,该数组里面的成员是整型的指针,分别指向int型的内存。注意,该地址类型是int [3]型,他的值是0x40004000,void (*va)(int) 这是一个指针,指向一个函数,这是一个整型指针变量,用于存放一个整型变量的地址,函数的形参是是int型,返回值是int型。这是一个指针,指向一个int型数组。
2025-04-03 14:23:47
167
原创 C结构体内存对齐
想象一下,你去超市购物,收银台前排了一长队。超市为了提高效率,规定:购买 1-3 件商品的顾客,必须站在 3 的倍数位置(第 3、6、9... 个位置)购买 4-7 件商品的顾客,必须站在 4 的倍数位置(第 4、8、12... 个位置)购买 8 件以上商品的顾客,必须站在 8 的倍数位置(第 8、16、24... 个位置)这样会怎样?队伍中肯定会出现空位!但收银员处理起来更有效率,因为他能快速判断每位顾客大概需要多长时间。内存对齐就是这个道理。
2025-04-03 14:19:44
863
原创 GDB调试工具详解
GDB,全称 GNU Debugger,是 GNU 开源组织发布的一款功能强大的程序调试工具。自 1986 年由理查德・斯托曼(Richard Stallman)编写以来,它不断发展和完善,如今已成为 Linux 系统下调试程序的首选工具 ,在整个 Linux 生态系统中占据着举足轻重的地位。它就像是一位经验丰富的侦探,深入程序的 “案发现场”,帮助开发者们找到隐藏在代码中的 “罪犯”——Bug。
2025-04-03 10:02:25
1116
原创 C++ Lambda 默认捕获缺陷
所以你看,默认捕获模式[&]和[=][&]可能导致悬空引用,像个不定时炸弹 💣。[=]对指针的捕获可能是悬空指针的温床 💀,而且它对static变量的“无视”会让你误以为 Lambda 是完全独立的,其实它可能还和外部状态藕断丝连。尽量避免使用默认捕获模式!老老实实地显式捕获你需要的每一个变量,无论是按引用[&var]还是按值[var](或者 C++14 的广义捕获这就像是在和编译器签合同 ✍️,白纸黑字写清楚你的 Lambda 到底依赖谁、怎么依赖。
2025-04-01 08:54:32
918
原创 C++线程池
线程池(Thread Pool)是一种预先创建并维护若干线程的并发编程模型,所有任务提交后由池内线程处理,避免频繁创建销毁线程带来的系统开销。资源复用:复用固定数量的线程处理大量短时任务控制并发:防止线程数无控制增长导致内存耗尽或CPU调度崩溃任务排队:合理调度和管理任务执行顺序。
2025-04-01 08:39:20
630
原创 5个C++ 语法糖让你的代码效率提升
在 C++ 的发展历程中,不断引入了许多新特性,这些特性就像语法糖一样,让代码变得更加简洁、高效和易读。今天,我们就来详细介绍 5 个实用的 C++ 语法糖:auto、lambda、范围for、nullptr和std::initializer_list,帮助你提升代码编写效率。
2025-03-31 08:50:09
597
原创 Qt多线程同步机制
在多线程编程中,常常需要确保多个线程对共享资源的访问不会产生数据竞争。为此,我们使用同步机制来保证线程安全。在Qt/C++中,常见的同步机制包括QMutexstd::mutexQSemaphoreQAtomicInt将详细介绍这些机制,配合代码示例和注释,帮助你理解这些工具在多线程中的应用。互斥锁是一种常见的同步工具,用于防止多个线程同时进入临界区(共享资源的代码段)。在任何时刻,只有一个线程可以持有互斥锁并进入临界区,其他线程必须等待锁被释放后才能继续执行。
2025-03-30 09:09:40
601
原创 Qt正则表达式QRegularExpression
正则表达式(Regular Expression,简称正则)是一个特殊的文本字符串,它描述了搜索文本的模式。我们可以通过正则表达式定义匹配规则,进而用于文本搜索、替换、验证和分组提取数据。正则表达式广泛应用于数据验证、文本解析等场景。在 Qt 中,类用来处理正则表达式。相比于旧版的QRegExp类,提供了更现代、更强大的功能,特别是支持 ECMAScript 标准,使得它能够处理更复杂的正则表达式。在 Qt 中,
2025-03-28 20:40:35
1086
原创 2025年15个图标库推荐
这几年写代码下来,我深深体会到:一个好的图标库对项目的影响有多大。图标不仅能提升用户体验,还能省去大量说明文字,让页面瞬间高级感满满。
2025-03-28 09:40:28
1286
原创 指针的前世今生
当然,指针的用途远不止于此。想象一下,你的程序中有上百个数据,你需要记住每个数据分别存在哪个具体地址,这简直是噩梦!它就像是一张写有门牌号的纸条,告诉你:"嘿,你要找的东西在这个地址!想象一下,计算机的内存就像一条超长的街道,街道上有成千上万的房子,每个房子都有自己的门牌号(地址)。这就好比:我不给你我家的钥匙副本,而是直接告诉你我家的地址,你可以直接来我家拿东西或放东西。,我们改变了指针所指向地址上的值,因此 number 的值也变成了100。时,又创建了一个新的副本,对这个副本的修改也不会影响原始的。
2025-03-26 09:12:36
641
转载 Qt进程间通信:QSharedMemory 使用详解
是 Qt 中用于进程间共享内存的类。它允许多个进程共享一块内存区域,从而避免数据传输时的 IO 操作,提高通信速度。通过共享内存,多个进程可以直接读写这块内存,而无需经过文件或网络传递。QSharedMemory 的核心特点唯一键(Key)标识每块共享内存通过唯一的键(字符串)标识。不同进程通过相同的键连接到共享内存。线程安全性提供锁机制(lock()和unlock())以保护共享内存的读写。跨平台支持Qt 的跨平台特性使可以在不同操作系统上无缝使用。
2025-03-24 12:14:53
1016
电力通信协议模拟工具 SimElecProtocol
2022-06-02
IEC61850 MMS客户端工具 V1.0.2
2018-11-12
SM2椭圆曲线算法软件.rar
2019-06-05
IEC61850 MMS客户端工具 V1.0.1
2015-06-25
NeHe OpenGL Qt4教学代码
2016-11-28
IEC61850 SCL文件Schema校验
2017-12-14
IEC61850服务端模拟软件 V1.0
2019-03-13
Qt+JS 饼,柱等图形展示
2016-07-04
IEC61850 MMS客户端工具
2015-06-11
久为影音 2.0.1
2017-09-07
IEC61850 SCL文件编辑工具
2014-12-09
久为影音 2.0
2017-09-07
久为影音 V2.0.2
2017-09-08
久为影音 V2.0.1
2017-09-08
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人