<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>yycoding-记录编程点滴</title><description>.NET Developer,前微软最有价值专家(2012-2016)</description><link>https://www.yycoding.xyz/</link><pubDate>Mon, 27 Apr 2026 18:32:51 GMT</pubDate><copyright> ©2011-2026 yycoding.xyz</copyright><generator>Moonglade v12.9.1</generator><language>en-US</language><item><title>基于BFS算法的停车场出库问题求解与实现</title><link>https://www.yycoding.xyz/post/2026/3/21/solution-and-implementation-of-the-parking-lot-exit-problem-based-on-bfs</link><description>本文以益智游戏《停车场出库（Car Park Puzzle）》为应用背景，针对其车辆调度与最短路径求解问题，展开广度优先搜索（BFS）算法的实践研究。该游戏借鉴华容道机制，要求在网格场地内按车辆方向约束移动车辆，将目标车辆引导至出口，中高难度关卡人工求解效率较低。文章在上一篇迷宫寻路算法的基础上，对比分析了传统迷宫 BFS 与停车场状态空间 BFS 的差异，详细阐述了从单点坐标搜索到全局局面状态搜索的算法升级思路。项目使用 C++ 结合 Qt 框架实现完整游戏系统，采用 CMake 构建，运行于 Windows+Visual Studio 环境。内容涵盖停车场网格与车辆的数据结构建模、游戏状态编码与去重策略、BFS 最优解搜索核心流程、最小步数证明、Qt 界面绘制、鼠标拖拽与键盘交互逻辑设计，并增加了搜索状态计数功能以评估算法效率。 …</description><author>xjdx2008@126.com</author><category>C++</category><category>Data Structures and Algorithms</category><guid isPermaLink="false">48C4D7C4-258A-4417-ADCA-93073AF70985</guid><pubDate>Sat, 21 Mar 2026 00:10:25 GMT</pubDate></item><item><title>使用C++和Qt从零开发一个光影边框程序</title><link>https://www.yycoding.xyz/post/2025/12/22/implement-a-image-frame-program-using-c-plus-plus-and-qt</link><description>今年双十一的时候我买了一部微单相机，拍完照片后给照片添加“边框水印”变得更好看了。 在这类应用中我最喜欢的是壹印，不论是软件的界面设计，还是生成的水印风格。于是在Gemini的辅助下，我使用C++和Qt复刻了这一款类似壹印水印效果的程序。我有C#经验和一定的C++基础，但从没有使用C++和Qt开发过窗体程序。从最初依赖 FFmpeg 的臃肿工具，到现在拥有自适应纸张纹理、柔光阴影、且体积轻量的原生 C++ 应用，这个项目不仅是代码量的增加，更是对架构设计（策略模式）、性能优化（算法自研）和工程化思维（工具集成） 的一次完整实践。 …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">A6D54F37-7CD4-40BE-B7C8-12B3BF5D7C9C</guid><pubDate>Sun, 21 Dec 2025 23:31:41 GMT</pubDate></item><item><title>C++语言演化中的审慎原则</title><link>https://www.yycoding.xyz/post/2025/7/3/the-principle-of-prudence-in-the-evolution-of-cplus-plus</link><description>本文深入剖析了C++语言演化中所秉持的“审慎原则”，论证了标准委员会（WG21）通过有意识地拒绝或搁置某些语言特性，从而成功维护了C++的长期稳定性与核心设计哲学。报告通过四个关键案例展开论证：一、在处理多重继承的虚函数名冲突时，委员会选择推广设计模式（适配器模式）而非引入新“重命名”语法，以避免语言膨胀。二、面对双重分发的需求，它采纳了访问者模式，拒绝了可能导致对象模型过度复杂化的原生语言支持。三、它坚定地拒绝内置垃圾回收（GC）机制，以捍G卫RAII范式、零开销原则及性能的确定性，这些是C++的立身之本。四、在类型推导上，它没有直接采纳当时已有但存在瑕疵的typeof，而是精心设计了语义更精确的decltype，彰显了对语言基础工具正确性的极致追求。综上所述，这些决策共同揭示了C++标准化过程中的一种成熟智慧：通过审慎的“减法”来保证语言的健壮、高效与持久生命力 …</description><author>xjdx2008@126.com</author><category>C++</category><category>Design Patterns</category><guid isPermaLink="false">50688FF9-93C7-468D-96DA-38271D0A271A</guid><pubDate>Wed, 02 Jul 2025 16:21:34 GMT</pubDate></item><item><title>CMake入门教程</title><link>https://www.yycoding.xyz/post/2025/7/1/a-brief-introduction-of-cmake</link><description>CMake已经成为C++生态系统中事实上的标准构建系统生成器。它通过将复杂的构建逻辑抽象到一个统一的、跨平台的脚本语言中，极大地提高了项目的可维护性和可移植性。掌握现代CMake，特别是其基于目标的依赖管理思想，是每一位严肃的C++开发者必备的技能。本教程从CMake的基础工作流程和核心语法出发，深入探讨了作用域、库的构建与链接、条件编译以及高级模块化技术。我们强调了“源码外构建”的重要性，详细解析了PUBLIC、PRIVATE和INTERFACE关键字在传递依赖关系中的核心作用，并针对Linux平台特别讲解了RPATH和$ORIGIN在创建可重定位软件包中的应用。通过对比function与macro、target_sources与file(GLOB)，我们阐明了现代CMake的最佳实践及其背后的设计哲学。最终，通过一个完整的实战项目，我们将所有理论知识融会贯通，展示了如何构建一个结构清晰 …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">B3D9ED25-75E6-4614-A1B2-176DCD0C228F</guid><pubDate>Mon, 30 Jun 2025 22:56:15 GMT</pubDate></item><item><title>C++中的shared_ptr、weak_ptr以及enable_shared_from_this</title><link>https://www.yycoding.xyz/post/2025/4/7/shared-ptr-weak-ptr-and-enable-share-from-this-in-cpp</link><description>在《Linux多线程服务器编程:使用muduo C++网络库》这本书中，作者在第15页一针见血的指出C++可能出现的内存问题的几个方面： 缓冲区溢出(buffer overrun) 空悬指针(dangling pointer 指向已销毁的对象或已回收的地址)/野指针(wild pointer 指的是未经初始化的指针) 重复释放(double delete) 内存泄漏(memory leak) 不配对的new[]/delete 内存碎片(memory fragmentation)  正确的使用智能指针可以解决前5个问题： 缓冲区溢出：使用STL中的容器( std::vector 、 std::string )、使用安全的拷贝函数，或者自己编写buffer class来管理缓冲区，自动记住缓冲区的长度，并通过成员函数，而不是裸指针来修改缓冲区 空悬指针/野指针：用 std::share_ …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">72CCBF3F-F4B2-4300-BB6C-8A24CA86A876</guid><pubDate>Mon, 07 Apr 2025 00:54:40 GMT</pubDate></item><item><title>C++编译器中最烦人的分析机制</title><link>https://www.yycoding.xyz/post/2025/3/26/the-most-vexing-parse-in-cplusplus</link><description>Scott Meyers 在《Effective STL》一书的第六条提出了一个“当心C++最令人烦恼的解析"(the most vexing parse)的问题。“the most vexing parse” 这个术语来形容 C++ 标准对于 declaration 语句的消歧义（ambiguity resolution）约定与常人的认知相悖。最令人烦恼的解析 （most vexing parse）是C++中的一种反直觉的二义性解析形式。 在一些场景下，编译器无法区分某语句是初始化时某对象的参数，还是声明一个函数时指定参数类型。在这些情况下，编译器将该行解释为函数声明。简言之就是“调用构造函数被误认为是函数声明的问题”，即 形如 Type() 或 Type(name) 的表达在某些情况下具有歧义（syntax ambiguity）。 …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">C966A0A9-6E1F-4047-8F56-2F59849821F9</guid><pubDate>Tue, 25 Mar 2025 23:19:48 GMT</pubDate></item><item><title>C++中的bind、function以及lambda表达式</title><link>https://www.yycoding.xyz/post/2025/2/20/bind-function-and-lambda-expression-in-cplusplus</link><description>在C++98中就有了函数对象（function object），为了方便从二元函数得到一元函数，引入了bind1st和bind2nd，这种场景在C++ STL中应用的很常见。随后C++11从boost库中引入了功能更强大的bind (以替代bind1st和bind2nd) 以及function函数对象机制。由于函数对象仍然需要额外定义，且有时很不方便，所以又引入了lambda表达式。 本文逐一介绍这些概念，以及背后的实现原理。 …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">BD587E78-D7F7-4842-9756-459885F758A4</guid><pubDate>Wed, 19 Feb 2025 21:33:30 GMT</pubDate></item><item><title>C++中的智能指针</title><link>https://www.yycoding.xyz/post/2025/2/13/smart-pointer-in-cplusplus</link><description>C++中堆上的动态资源管理是一个容易出错的地方，借助RAII（Resource Acquisition Is Initialization，资源获取即初始化），能够简化资源管理，依此思想产生的智能指针极大的简化了编程。 本文先简要介绍C++中资源管理，然后介绍RAII，最后在这些概念上实现一个简单的不带引用计数的智能指针和带引用计数的智能指针，以加深对这些知识的理解。 C++中的栈、堆及资源管理 与C#中的概念相似，在C#中，值类型的对象大多数情况下是在栈上分配的，而引用类型的对象，则默认在堆上分配，这些都是默认行为，不需要手动指定，栈上的内存在出作用域后会被回收，而堆上的内存，则由垃圾回收器负责回收。 在C++中则复杂的多，它有三块内存区域： 静态内存，用来保存局部static对象、类的static数据成员，以及任何定义在函数之外的变量，分配在静态内存中的对象由编译器自动创建和销毁。 …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">5F31B2CF-87FD-41E5-889C-B2456296D070</guid><pubDate>Wed, 12 Feb 2025 21:43:12 GMT</pubDate></item><item><title>C++中的Copy-And-Swap惯用法</title><link>https://www.yycoding.xyz/post/2025/2/10/the-copy-and-swap-idiom-in-cplusplus</link><description>在C++中，有个著名的The Big Three,即：如果要显示声明析构函数、拷贝构造函数和拷贝赋值操作符，那么需要显示声明所有的这三者。拷贝构造函数和析构函数实现起来比较容易，但是拷贝赋值操作符则要复杂很多。因为与拷贝构造不同，拷贝赋值需要先把当前的资源释放，然后重新构造。这与之前单例模式中的某些场景一样，有许多需要注意的问题。copy-and-swap就是完美的解决方案。它可以很好地帮助拷贝赋值操作符达到两个目标：避免代码重复、提供强烈的异常安全保证。 …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">3D65A8EA-C7BF-45F4-A875-093DCEA914CF</guid><pubDate>Mon, 10 Feb 2025 01:22:56 GMT</pubDate></item><item><title>C++中的移动语义和完美转发</title><link>https://www.yycoding.xyz/post/2025/2/7/move-semantics-and-perfect-forwarding-in-cpp</link><description>在C++中，对象默认都是值语义，比如在对象A里面定义了成员变量B和C，那么B和C会被直接放在A的内存空间里，这样做的优点是保证了内存访问的局部性，这在现代处理器架构上具有绝对的性能优势。但缺点是，在对象复制时，具有很大的开销。而在Java或者C#里面，默认存储的是引用或者说是指针。因为C++存储完整对象这个特性会导致大的复制开销，所以C++需要移动语义这一优化，而在Java或者C#中则根本不需要这一概念。一句话总结就是，移动语义使得C++里返回大对象（比如容器）的函数和运算符的性能得到极大提高。 …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">B7714CBE-67E3-4053-BD0A-0AE2E824A53E</guid><pubDate>Fri, 07 Feb 2025 00:23:19 GMT</pubDate></item><item><title>C++中的容器空间分配器</title><link>https://www.yycoding.xyz/post/2024/12/31/container-allocator-in-cplusplus</link><description>在C++中，对象可以粗略的分为两大类，一类是基础对象，它不包含对外部堆上对象的引用，比如普通的编译器内置类型，这类对象的构造函数和析构函数系统可以默认生成且满足要求，拷贝构造函数和拷贝赋值运算符都是默认的对内存的拷贝，这些也大都满足要求。另外一大类是对象包含指针，即包含有指向堆内存对象的引用。所以在涉及到容器的时候，就有必要将对象的内存分配和构造，内存释放和析构分开来，这就是容器的空间分配器的作用，更进一步容器的空间分配器还可以对内存分配进行池化管理从而提升内存使用效率。本文就简单介绍以下为什么容器需要空间分配器，以及一个简单的空间分配器的实现。 …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">A33061BB-E881-47E8-A2CD-B655D730FEE4</guid><pubDate>Mon, 30 Dec 2024 22:20:40 GMT</pubDate></item><item><title>实现端口转发的几种方法</title><link>https://www.yycoding.xyz/post/2024/8/30/several-methods-for-implementing-port-forwarding</link><description>端口转发在有些时候还是比较有用的，它能够在数据传输的过程中增加一个“路由”，提供了某种程度的灵活。本文简单介绍了工作中遇到的一个可能使用端口转发能解决的例子，以及如何使用端口转发，包括介绍了在Windows上的内置的端口转发工具，以及一些开源的端口转发程序，最后再简单介绍了如何使用C#实现一个端口转发工具。 …</description><author>xjdx2008@126.com</author><category>C++</category><category>DotNet Framework</category><guid isPermaLink="false">712DDBA1-4C82-41C1-B1A8-1F1FCDE9F329</guid><pubDate>Thu, 29 Aug 2024 22:54:35 GMT</pubDate></item><item><title>浅谈字符编码</title><link>https://www.yycoding.xyz/post/2024/8/19/a-brief-introduction-about-character-encoding</link><description>前段时间用C++写了个批量改文件名的小工具，发现在改英文文件名的时候正常，但是遇到中文文件名就会失败。调试过程中发现，中文文件名在程序里得到的是乱码。这个问题在VS Code中很明显，只要是在VS Code的控制台里输出中文字符，大概率乱码，所以在在使用VS Code练习C++的时候，很少使用中文字符。这个问题我也一直没有深究，最近看了字符编码的相关知识，这里总结记录一下。为了了解乱码，需要了解什么是字符编码，本文介绍了一些常用的编码比如ASCII、GB2312、GBK、Unicode、UTF-8、UTF-16、UTF-32，在此过程中也介绍了大端小端的概念以及字节顺序标记BOM相关知识。 …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">367EA12B-CF50-4DD9-AC2B-1057FDA9BAAE</guid><pubDate>Sun, 18 Aug 2024 22:10:03 GMT</pubDate></item><item><title>使用可变参数模板和CRTP实现访问者模式</title><link>https://www.yycoding.xyz/post/2024/7/13/refractor-the-visitor-pattern-implementing-using-cpp-variadic-templates-and-crtp</link><description>Visitor模式的一大缺点就是依赖问题，在定义Visitor接口的时候，就必须要知道所有的子类类型。在一些编译链接型语言如C++中，Visitor类和子类就会出现相互依赖的情况，当然，通过前向声明可以解决这个问题。另外一个问题就是在不同的子类中有很多“制式”代码。比如所有的子类必须实现基类中的Accept(Visitor&amp;)方法，并且方法的实现都是一模一样的，都是调用该参数的Visitor方法并传入指向对象本身的引用。幸好在C++ 11中引入了可变参数模板，使用可变参数模板以及CRTP技术，可以极大简化Visitor模式中的一些实现方面的问题。在这一过程中顺便学习和了解Moden C++的一些强大的功能，这些功能是如此的特别以至于它跟C#有很大的不同。 …</description><author>xjdx2008@126.com</author><category>C++</category><category>Design Patterns</category><guid isPermaLink="false">DC284C23-5EDC-420A-9F57-C7B13183DEB0</guid><pubDate>Fri, 12 Jul 2024 18:58:40 GMT</pubDate></item><item><title>C++中的可变参数模板</title><link>https://www.yycoding.xyz/post/2024/7/8/variadic-templates-in-cplusplus</link><description>本来是想接着上文继续来说明如何使用C++模板来简化Visitor设计模式的，但这里涉及到了C++ 11中引入的可变参数模板，这个特性很有用，所以值得专门写一篇文章来介绍一下C++中的可变参数模板。可变参数模版比较特殊，跟其它语言比如C#里面的params相比，似乎更加灵活和强大。

当然我没有能力对某个特性做全面的解读，可变参数模板有很多用处，这里列举了侯捷老师在《 C++新标准：C++11&amp;14》课程里对可变参数模版的解读里面举的几个例子，这几个例子比较经典，完美的解释了可变参数模版的用法。这篇文章算是一个简单的笔记，C++里面有些特性需要反复的学习和复习才能掌握。 …</description><author>xjdx2008@126.com</author><category>C++</category><category>Design Patterns</category><guid isPermaLink="false">D056F3D0-5362-4732-9C41-CBC0F627EAF1</guid><pubDate>Sun, 07 Jul 2024 16:21:26 GMT</pubDate></item><item><title>从双分发的视角看访问者模式</title><link>https://www.yycoding.xyz/post/2024/6/15/inspect-visitor-pattern-from-double-dispatch-perspective</link><description>在23种经典设计模式中，Visitor模式可能是比较难理解的几个模式之一，之前在C#设计模式之访问模式这篇文章中渐进式的介绍了Visitor设计模式。恰巧最近看的《C++语言设计与演化，简称D&amp;E》这本书中提到了一个单分派和双分派的概念，这里从前文介绍的C++中的虚函数表以及动态分发即单分发的基础上，介绍双分发以及基于双分发的Visitor设计模式，试着从另外一个角度来看访问者这一经典的设计模式，最后对比了通过工厂方法和访问者模式的异同。 …</description><author>xjdx2008@126.com</author><category>C++</category><category>Design Patterns</category><guid isPermaLink="false">D80163F9-ABD8-46C0-8966-3800D1A67D03</guid><pubDate>Sat, 15 Jun 2024 05:26:31 GMT</pubDate></item><item><title>C++中的成员指针</title><link>https://www.yycoding.xyz/post/2024/5/19/pointers-to-members-in-cpp</link><description>C++的有些知识点可能不在《C++ Primer，5th》或者《The C++Programming Language，4th》里，作为一个看这两本书的初学者，这有些难办。C++的有些知识藏在犄角旮旯里，但时不时就能碰到，今天就谈谈遇到的成员指针。跟C#或者Java中成员变量或者函数必须定义在类里面不同，C++中的成员变量或者函数既可以写在类的外面，也可以写在类的里面，这或许是为了兼容C的缘故。针对指向的是否是成员变量或成员函数，C++中必须要进行区分，这或许就是成员指针的由来，本文简单介绍C++成员指针中的成员变量指针和成员函数指针。 …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">3C4AC531-5506-45B5-8275-3AA84FB4CD2F</guid><pubDate>Sun, 19 May 2024 00:10:46 GMT</pubDate></item><item><title>C++中的虚函数表以及动态分发</title><link>https://www.yycoding.xyz/post/2024/5/12/vtable-and-dynamic-dispatch-in-cpp</link><description>在C++中，如果一个类有虚函数，那么该类的对象在实例化后，会多一个指向虚函数表(virtual table, vtbl)的指针(vitrual table pointer, vptr)。虚函数表及虚函数调用是C++实现多态或者说动态分发(dynamic dispatch)的基础。本文首先介绍一下C++中的对象的虚函数指针以及类的虚函数表的结构，然后介绍了通过使用虚函数表实现动态分发的原理，最后讨论了虚函数调用的性能。 …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">43BB41F2-F02C-4093-87E6-C79212631BDF</guid><pubDate>Sun, 12 May 2024 00:21:28 GMT</pubDate></item><item><title>使用Windows Subsystem for Linux安装Ubuntu以及配置C++开发环境</title><link>https://www.yycoding.xyz/post/2024/4/13/installing-ubuntu-and-configuring-cpp-development-environment-using-windows-subsystem-for-linux</link><description>随着Windows开始拥抱Linux，在Windows 10以及之后的操作系统里内置了Windows Subsystem For Linux（WSL）模块，可以很方便的在Windows上使用和体验Linux，并且资源开销相对于虚拟机来说要小的多，相当于在Windows上安装了一个名为Ubuntu的应用，并且可以在Windows上直接访问和查看Linux下面的文件系统。我初步体验下来还是非常友好和方便的，Linux操作起来在有些情况下就是比Windows下面更加直接和高效。本文记录一下在Windows 11上启用WSL，安装Ubuntu，以及Ubuntu里面搭建C++的基本开发环境的步骤，算是一个笔记，后面在熟悉Linux操作系统以及学习C++的时候，直接就可以使用WSL里面的Ubunut环境。 …</description><author>xjdx2008@126.com</author><category>C++</category><guid isPermaLink="false">1FFA9235-7DAA-43C1-A869-069ACDC7CF85</guid><pubDate>Sat, 13 Apr 2024 02:54:19 GMT</pubDate></item><item><title>告别暴力终止线程</title><link>https://www.yycoding.xyz/post/2023/11/15/say-goodbye-to-brute-force-stop-a-thread</link><description>有时候需要让一个线程终止运行，.NET Framework的Thread类中提供了Abort方法，调用某个线程实例对象的Abort方法，可以让该线程类抛出一个ThreadAbortException从而终止该线程的运行。但使用Abort方法终止一个线程对象显得比较暴力，而且可能会有很多潜在的问题，尤其是一个线程调用另外一个线程的Thread.Abort方法终止时。好消息是从.NET 5.0开始Thread.Abort方法就已经被弃用，如果调用就会抛出“PlatformNotSupportedException”，本文主要介绍简单粗暴杀手线程的可能危害，以及如何优雅地退出线程的方法。 …</description><author>xjdx2008@126.com</author><category>C++</category><category>DotNet Framework</category><guid isPermaLink="false">46FB9D4F-BD3A-453C-95FB-B016519E0B7B</guid><pubDate>Wed, 15 Nov 2023 01:25:04 GMT</pubDate></item></channel></rss>