- 博客(83)
- 资源 (5)
- 收藏
- 关注
原创 SFINAE 检测惯用法(detection idiom)
先来看一段代码:这段代码是 C++ 里非常经典的 SFINAE 检测惯用法(detection idiom),用来在编译期判断一个类型 是否拥有可被 调用的成员函数 。下面逐层拆解。二、逐行解析1. 主模板 — 兜底默认值 注意第一个模板参数 没有名字。这个“无名占位参数”是整个技巧的关键:它不是用来存储类型信息的,而是专门留出来给偏特化去“填充 SFINAE 表达式”的槽位。当偏特化匹配失败时,编译器回退到这个主模板,得到 (即“不具备 emplace_bac
2026-10-16 11:56:19
96
原创 RAII(Resource Acquisition Is Initialization)详解
RAII 就是把「申请资源」放进构造函数、「释放资源」放进析构函数,借助栈对象必然析构这一机制,让资源生命周期和对象生命周期完全绑定,从而在不写一行手动清理代码的前提下,彻底杜绝内存泄漏、死锁和文件句柄泄漏。
2026-10-16 10:48:16
331
原创 深入理解std::declval的概念与用法
它只有声明、没有定义(所以永远不能被实际调用、不能被 odr-use)。它的返回值类型是T&&(或T&当编译器读到类的定义时,它不是把类当成"运行时才能造出来的东西",而是立刻解析并归档成一份类型信息。// 声明编译器解析完这段后,会在符号表里给Vec符号表条目:Vec└─ 成员函数列表:├─ emplace_back : 参数 (double) → 返回 int, 无 const└─ size : 参数 () → 返回 int, 有 const这些信息在编译期就固定下来了,跟内存里有没有Vec。
2026-10-16 10:33:02
131
原创 C++指针悬空
指针悬空(Dangling Pointer)是C/C++里最常见、也最难排查的内存错误之一,本质是:指针/引用本身还存在,但它指向的内存已经被释放、销毁或者失效了,此时再通过这个指针访问内存,就会触发未定义行为。指针本质就是一个存内存地址的整数变量:局部变量是分配在栈上的,函数返回时栈帧销毁,局部变量的内存会被自动回收:种情况最坑:你测试的时候可能一直"正常工作",因为刚释放的栈内存还没被其他函数调用覆盖,一旦后续调用其他函数、栈空间被复用,读到的就是随机垃圾值,bug极难复现。堆上分配的内存手
2026-10-13 10:52:44
285
原创 一款集结古今中外文学查阅与编辑的软件
作为一名编程爱好者,花了近两年的业余时间,用QT开发了一款文学知识查阅与编辑软件(目前仅限windows系统和单机环境)。准确的说,它包括两个可执行文件,一个用于文学编辑(取名为“萃辞笺”),一个用于文学查询(取名为“萃辞观”),
2026-08-31 00:05:33
226
原创 QT 隐式共享/写时复制详解
b = a;a[0] = 5;*i = 12;输出结果是:5 0 05 12 12是不是有些出人意料?为何会出现这种现象,原因是QVector是隐式共享(copy-on-write)的容器。以上代码中,b = a;并不会马上复制一份独立的数据。它只是让b和a共享同一块内部数据缓冲区。a和b共享同一个数据内存,i仍然指向那块内存。本质上指向内部数组,当修改a或b时,若发生写时复制(detach),迭代器可能失效。修改迭代器 i 就是用了隐式共享容器的 “裸指针式” 修改方式。
2026-06-09 18:42:51
307
原创 qss/css 样式中margin和padding的作用和区别
这里的 contentsRect 是由 QWidget::contentsMargins 决定的,不是由 QSS 的 padding 决定的。用 layout 的 contentsMargins,不是控件样式表的 padding/margin。最容易混淆的是:Qt 里还有布局的 margin,这和 QSS 的 margin 不是一回事。先看两张图,分清“样式表盒模型”和“QWidget 几何系统”,后面就不容易混了。也就是说 margin 区域通常是“外部空白”,不是控件背景的一部分。
2026-05-30 12:03:23
456
原创 QTextDocument 功能和用法详解
它本身不负责“像浏览器那样显示网页”,而是把文本、段落、图片、表格、列表、块级格式、字符级格式这些内容组织成一个可布局、可绘制、可编辑的文档树,然后交给布局器去排版,再交给绘制层输出到屏幕、打印机或任意 QPainter 目标。QTextDocument 相关类关系图,将QTextCursor、QTextBlock、QTextLayout、QAbstractTextDocumentLayout 一次串起来。更有效的是按职责完整梳理。它不是简单字符串,而是有行列、单元格、单元格格式、列宽约束的真实文档对象。
2026-05-30 11:43:58
368
原创 QT 实现多种格式的图标(包括png、ico、svg等)相互转换
1、支持png、jpg、jpeg、ico、bmp、svg格式的图标相互转换格式(如下图所示)2、选取本地的图标后,可以显示图标的格式和尺寸,并有预览的功能;花了几个晚上,制作了一款多种格式的图标相互转换的小工具软件(3、可以选择需要转换的格式,可修改保存图标的路径和尺寸。源代码和打包的可执行文件见文章末尾。
2026-05-21 00:22:55
138
原创 C++ Coroutines(协程) 详解
它不能像某些有栈协程那样在任意深层函数处直接切出去,只有在显式的 co_await、co_yield、co_return 这些语义点才能挂起。这段代码虽然没什么实际用途,但足以说明一件事:协程返回类型背后必须有一个 promise_type,编译器靠它决定如何构造、挂起、恢复和结束协程。让你看到 promise 怎么保存结果,handle 怎么 resume,co_await 怎么取值。也就是说,co_await 不是“等待某个固定类型”,而是等待“任何实现了 await 协议的对象”。
2026-05-18 10:56:25
498
原创 重写QWidget,实现QLineEdit的基本功能
负责 text、cursor、selection、preedit、maxLength、echoMode。只有在你要完全自绘、自己控制光标、选区、输入法、焦点行为时,才建议直接继承 QWidget 重写。如果只是想改样式、限制输入、加按钮、改行为,优先继承 QLineEdit。负责 insert、delete、replace、undo、redo。把插入、删除、替换封装成命令,顺手就能加 undo/redo。负责边框、文本、选区、光标、占位文本、滚动偏移。负责键盘、鼠标、输入法、剪贴板、焦点和快捷键。
2026-05-15 18:48:27
176
原创 重写QWidget,实现弹出下拉菜单的功能
QT 重写QWidget,实现以下功能:1、点击弹出下拉菜单,再次点击隐藏下拉框;2、弹出下拉框后,点击QWidget外,隐藏下拉框。
2026-05-15 18:00:58
190
原创 浮点数在计算机中存储格式详解
在计算机里不是直接存“9.721 这几个十进制字符”,而是先转成二进制科学计数法,再按 IEEE 754 的。本文再讲解浮点数再计算机中存储的详细过程,比如double类型的9.721的整个转换和存储过程。要靠“乘 2 取整”反复展开,它不是一个有限二进制小数,所以会变成无限展开。,编译器会把它转换成“最接近 9.721 的那个 binary64 值”。这就是为什么浮点数经常会出现“看起来一样,底层并不完全相等”的现象。先按主流平台讲:在绝大多数 PC 和服务器上,C++ 里的。
2026-05-15 11:23:13
461
原创 深入了解浮点数在计算机中的存储方式和运算
浮点数是用“符号 + 指数 + 尾数”按二进制科学计数法存的,能表示小数和很大范围,但很多值只是近似值;速度上不能绝对说谁更快,但通常整数更直接,浮点更复杂,而现代 CPU 上浮点加减乘也已经非常快。
2026-05-15 11:09:43
434
原创 C++ 标准库常用函数(sort, transform, accumulate, reduce等)
下面这几个都是 C++ 标准库里非常常用的算法。先给你一个总图,便于建立感觉:如果只看本质,可以把它们分成三类:下面按“作用 + 用法 + 示例 + 注意点”讲。准备知识常用头文件:示例里默认都用 。作用对区间内每个元素执行一次操作。你可以把它理解成:“把一个函数应用到每个元素上”。基本写法std::for_each(begin, end, func);示例 1:打印所有元素输出:1 2 3 4 5示例 2:原地修改元素注意这里 Lambda 参数要写成引用。输出:2 4 6 8 10什么
2026-05-15 09:35:03
629
原创 C++11使用chrono获取当前时间戳
使用<chrono>的。注意防止编译器优化。多次测量取平均更可靠。对于复杂的性能分析,建议使用专门的 Profiler(如 perf, VTune)或 Google Benchmark 库。如果需要测量一个函数在真实环境中的耗时(包含 I/O、锁竞争等),可以保持函数原样测量;如果只测量算法 CPU 时间,需排除其他干扰,可以多次调用取最小值或使用配合高优先级线程。
2026-05-14 18:14:57
355
原创 C++ string 和string_view的区别和用法
所以如果你把 string_view 直接丢给只接受 C 字符串的接口,就可能出问题。string_view 是 C++17 引入的,表示“对一段字符串的只读观察”。而 string_view 只是“知道长度”,不是“保证以 '\0' 截止”。这里放进容器里,通常应该存 string,而不是存 string_view。性能提升的前提是你真的只是读,不是存,不是改,不是跨生命周期保留。string_view 不拥有数据,所以它依赖原字符串继续存在。string 的 substr 会构造新字符串,通常会拷贝。
2026-05-14 16:47:14
920
原创 C++ thread的detach()方法详解
深入讲解thread中的detach()方法和本质,并将它与join()进行对比。另外,还总结了一些容易踩坑的地方
2026-05-14 15:53:33
647
原创 C++ 回调函数详解和常用场景
传统做法是函数指针,现代 C++ 更常用 Lambda、std::function,成员函数回调通常通过 Lambda 或 bind 绑定对象来实现。函数指针、Lambda、仿函数、成员函数加对象、std::bind 生成的可调用对象、std::function 统一包装。普通函数、函数指针、Lambda、仿函数、成员函数配合对象、std::bind 结果、std::function。也就是说,不是你主动直接调用它,而是你把它注册出去,等事件发生、任务完成、条件满足时,由别的代码来调用它。
2026-05-14 10:48:30
610
原创 C++ thread 详解,附上代码示例
C++ 里的线程,通常指一个进程内可以并发执行的独立执行流。如果编译器支持 C++20,很多时候 std::jthread 比 std::thread 更好用,因为它析构时会自动 join,不容易忘。线程池通过复用固定数量的工作线程,从任务队列取任务执行,能显著降低调度开销,适合大量短任务。多个线程在没有同步的情况下,同时访问同一块内存,并且至少有一个是写操作,这就是数据竞争,结果属于未定义行为。如果只是做简单计数、自增、自减、状态位修改,可以用 std::atomic,通常比 mutex 更轻量。
2026-05-11 13:53:10
660
原创 C++ using typedef #define 三者的优缺点比较
它不只是做类型别名,还能做 using declaration、using namespace,所以初学时容易混淆。C++11 之后,using 是主流写法,和 auto、decltype、模板代码风格更统一。因为它不是类型系统的一部分,和 using / typedef 不是一个层面的工具。尤其是函数指针、成员函数指针这类,using 通常比 typedef 清楚很多。尤其是复杂类型,比如函数指针、模板类型,using 明显更直观。比如宏开关、平台适配、头文件保护,这些仍是它的传统强项。
2026-05-09 17:04:48
214
原创 深入详解C++ move语义与移动构造函数
move 语义指的是:当一个对象即将被销毁、不会再被使用时,不再做“拷贝资源”,而是把它内部持有的资源“转移”给另一个对象。典型资源包括堆内存、文件句柄、socket、锁的所有权等。移动构造函数它是类里的一个特殊构造函数,专门负责“从另一个右值对象接管资源”。
2026-05-09 16:25:13
410
原创 C++11到C++26常用语法和std算法详解,并列举出代码示例
这些一直是 C++ 社区高度关注的话题,但实际标准纳入、语法形式、编译器实现不能一概而论。、更多 range adaptor 在不同实现里逐步可用,但不同标准库落地不完全一致。这些是长期演进主线,但具体落地内容要看你使用的 GCC/Clang/MSVC 版本。重要:它们不真的删容器元素,只是“重排并返回新区间尾”。最有效的学习方式不是死记函数名,而是按“问题类型”记。这些更偏底层,面试不一定高频,但写泛型库时重要。用途:在未构造内存上构造对象,常见于容器实现。这是 C++20 最重要的库升级之一。
2026-04-27 12:02:29
382
原创 C++11完美转发的作用和用法
如果调用 wrapper(x),x 是左值,那么 T 会推导成 T = int&,最后 std::forward<T>(arg) 还是左值。如果调用 wrapper(10),10 是右值,那么 T 会推导成 T = int,最后 std::forward<T>(arg) 是右值。完美转发的作用,是在“包装函数”里把参数原样传给下一级函数,不改变它原本的左值/右值属性,也尽量不引入多余拷贝。如果传来的是左值,就保持左值。是危险的,因为调用者传来的是左值,但你擅自把它当成“可被拿走资源”的对象了。
2026-04-24 18:25:25
392
原创 decltype(x)与decltype((x))的区别
对未加括号的变量名 x,decltype(x) 得到的是变量的声明类型。这不是引用,只是新建了一个 int 变量,把 x 的值拷贝过去。对左值表达式,decltype((x)) 得到的是 T&。对加了括号的 (x),它变成了一个左值表达式。这是引用,ref_x 和 x 指向同一个对象。
2026-04-24 18:18:46
66
原创 C++ 指针传参测试
可以看到,点击按钮2没有打印信息,因为调用createAnimal2(SAnimal *ani)时,指针是值传递(传递的是指针值的副本),因此函数执行完后指针ani依然是空,只有传入指针的地址(即&*或**)才生效。答案是显然的,不管是传入指针,还是指针的地址,指针a的值在函数中被修改后都生效。假如有一个类A(非空),将其作为形参传入函数中,在函数中修改它的值,会生效吗?然而如果指针a是空指针,它是在函数内被创建的,那结果如何?
2025-09-12 19:22:39
269
原创 Qt 调用setLayout后,父对象自动设置
【分析】由于m_wgt嵌入在vLay布局中,而vLay的父对象是this,因而m_wgt的父对象也变为this。由于调用了m_wgt->setLayout(hLay),因而hLay的父对象是m_wgt(QObject对象在释放资源时,会自动释放它子对象的资源,相信大家都明白,因为QObject有一个QObjectList类型的对象,专门管理子对象,包括释放自身资源前会遍历释放子对象资源。关闭对话框后,m_lbInfo没有调用析构函数,与hLay都存在内存泄漏的风险(因为没有父对象,不会自动释放资源)
2025-09-12 17:12:44
523
原创 QTextLayout 的封装与功能测试
1、可以看到,QTextLayout可以精确地计算出多行文本内容的高度,文本可以完美的填充在组件内;2、QTextLayout能够支持字符串中的制表符(\t),但是不支持字符串中的换行符(\n),因为QTextLayout主要用于单段文本的布局,如果在传递给`QTextLayout`的字符串中包含换行符(`\n`),那么这些换行符会被视为普通空白字符,并不会导致换行。
2025-06-25 20:30:57
1210
原创 QTableView与QStandardItemModel的应用(含示例代码)
QStandardItemModel 是 Qt 框架中用于管理表格、列表或树形数据的通用模型类,基于 QAbstractItemModel 实现,提供了一种简单灵活的方式来处理结构化数据。通过灵活使用数据角色、信号槽机制和委托,可以轻松实现复杂交互和样式。(以下基础知识来源于DeekSeek,我没它总结的好,就借用它的术语,只整理了文本格式,博主自己写的示例代码在第二章)适合快速开发,但对超大数据量(如百万行)性能较低,此时建议自定义模型。对象,封装单元格的数据、样式和角色。自动处理数据更新和视图同步。
2025-05-03 15:47:32
1232
原创 Qt 5.15 编译路径吐槽点
在Qt 5.15以前,勾选“Shadow build”会自动将编译文件放在同一个目录下(区分编译器类型、Qt版本、debug和release等),可将代码文件和编译文件区分开,用户不用操心。不得不吐槽,这个界面做的是真的丑,只有鼠标停留在变量上才显示具体信息,查看极不方便,为啥不做个表格之类的,表格下一列直观显示变量的具体信息。虽然这样配置更灵活,但配置确实麻烦,网上没找到相应的方法,需要自己摸索,每个项目都需要手动配置一遍,而且debug和release都需要各自配置,费时费力。
2025-04-26 12:48:47
407
QT 实现多种格式的图标(包括png、ico、svg等)相互转换
2026-05-21
Qt 版Word多文档编辑与处理(完整版)
2021-08-25
Qt 桌面数字电子钟(可拖曳)
2021-08-25
Qt相片浏览(支持导入相片,相片放大和缩小,自动浏览等功能)
2021-08-17
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅