
C/C++知识
文章平均质量分 90
介绍C++开发工程师必备的小知识。
编码时空的诗意行者
十年互联网大厂老司机
展开
-
C++的STL_swap trick和现代C++的方法
我们都知道,std::vector的内存增长是随着元素的增加自动增加的,但是std::vector却没有相应的随着元素的减少自动释放内存的逻辑。因此,假设我们有下面的这样的类://…//这样写,m_data的内存是不会释放的,// 假设data占用了大量的内存,那么我们就达不到释放内存的目的在C99时代,如果要正确释放内存,我们需要这样写://…// 把一个临时的空的vector和m_data的内存交换,原创 2024-12-23 09:51:15 · 777 阅读 · 0 评论 -
C++源文件扩展名的历史和发展
C++ 源文件的扩展名反映了技术发展的历程和不同项目及组织的编码规范。从 C 语言的 .c 和 .h 到 C++ 早期的 .cc,再到最通用的 .cpp 和 .hpp,这些扩展名不仅帮助开发者区分不同的文件类型,还体现了 C++ 语言的演变和社区的多样化需求。无论选择哪种扩展名,都是C++代码承载容器的标识,见证了C++悠久的历史。原创 2024-12-23 09:47:03 · 1242 阅读 · 0 评论 -
造轮子:手把手写一个高质量高性能的C++日志工具【精】
笔者很好奇如果用最新的C++技术实现一个精简强大的日志工具是什么体验,今天跟笔者一起展开这次编程冒险旅程吧!原创 2024-10-12 11:33:47 · 1097 阅读 · 2 评论 -
C++:你知道POD类型(Plain Old Data)吗?
C++11标准引入了两个新的概念,分别是标准布局类型(Standard-layout)和平凡类型(Trivial)。其中,标准布局类型主要关注对象在内存中的布局,而平凡类型关注对象的生命周期,包括它的构造、拷贝、移动和析构。C++11以及之后的标准中,POD类型是同时满足标准布局和平凡类型的类型。原创 2024-09-27 18:02:31 · 850 阅读 · 0 评论 -
用最新的C++技术,如何实现一个序列化工具库?
随着C++标准的不断进化,实现简洁又实用的序列化工具变得越来越简单。目前我们还无法完全实现对结构体无侵入地实现反射,但是未来即将可以轻松实现。原创 2024-09-24 14:31:06 · 964 阅读 · 0 评论 -
命途多舛的Concepts:从提出到剔除再到延期最后到纳入,Concepts为什么在C++中大起大落?
在深入讨论Concepts的历程之前,我们首先需要明确概念本身。C++的Concepts在C++20标准中正式成为语言的一部分,它们为模板编程引入了一种类型约束系统。Concepts的核心目标是提高模板代码的可读性、可用性,同时让编译器能够提供更准确的错误信息,简化模板元编程的复杂性。C++的Concepts代表了语言演进的一种动态平衡。在追求技术卓越的同时,C++社区也在不断地反思和调整,以确保新特性的引入既能够带来实际的好处,也不会过度地增加语言的复杂性。原创 2024-08-01 11:48:20 · 994 阅读 · 0 评论 -
从《代码的艺术》中寻求“好代码”的要素
写出优质的代码,我们更需要更加关注:鲁棒(Solid and Robust)、高效(Fast)、简洁(Maintainable and Simple)、简短(Small)这四方面的要素,这四方面要素放在最前面,除了彰显其重要性外,更需要长期坚持和努力才能达到。加深对这些理念的理解,并运用于日常开发活动不断实践和感悟,必能看到更多的“好代码”在软件实践中绽放光彩,共同推动项目向着更高的技术标准迈进。《代码的艺术》是一本深入探讨软件开发哲学与实践的书籍,其中深入地讨论了 “好代码” 的特点。原创 2024-07-26 10:18:05 · 315 阅读 · 0 评论 -
C++实用指南:Lambda 表达式的妙用
Lambda 可以与算法结合使用,以实现自定义的迭代行为。});Lambda 表达式由于其匿名和内联特性,对于创建简洁、灵活的代码非常有用,它们已经成为现代C++编程中不可或缺的工具。原创 2024-07-25 18:17:01 · 594 阅读 · 0 评论 -
在C++里如何释放内存的时候不调用对象的析构函数?
这个面试题既有趣也有深度,它提供了一个探讨C++语言内存和资源管理机制的机会,同时考察面试者对C++底层细节的了解程度。然而,在实际的软件开发中,绝大多数情况下都应该遵循RAII原则,让析构函数自动管理资源的释放。原创 2024-07-24 11:56:05 · 1650 阅读 · 0 评论 -
从历史上最昂贵的空指针崩溃,论指针判空的重要性
2024年7月18日,美国信息安全巨头CrowdStrike推送的软件更新存在严重错误,导致全球范围内大量使用其软件的Windows电脑集体陷入“蓝屏”状态,无法正常使用。这场波及多个行业的“蓝屏”事件,不仅使多国航空、铁路、银行等基础设施服务中断,例如,特斯拉工厂生产因此暂停,马斯克称其为“史上最大IT失败”(Biggest IT fail ever),以此为导火索,特斯拉市值下跌了319.87亿美元。这次蓝屏的罪魁祸首,就是指针未判空导致的。原创 2024-07-22 15:06:34 · 750 阅读 · 0 评论 -
C++宏魔法:__VA_OPT__操作
_VA_OPT__被设计用于处理可变参数宏(variadic macros)中的逗号插入或移除问题。这个宏是在C++20标准中引入的,用于解决在可变参数宏中逗号操作的不确定性,特别是在需要条件性地添加或去除逗号的情况下。在C++中,可变参数宏允许宏接受不定数量的参数。它们由_VA_ARGS_标识符标识,代表了宏调用中传递的所有额外参数。原创 2024-07-15 11:32:00 · 1679 阅读 · 0 评论 -
如何写出清晰简洁的代码(通过一个实际的案例说明)
在软件开发中,清晰和简洁的代码是项目长期健康的关键。易读的代码不仅便于维护,还能减少错误的发生。通过分析一个具体的代码示例,我们来探讨如何提升代码的可读性和简洁性。原创 2024-07-11 10:33:11 · 599 阅读 · 0 评论 -
深入剖析C++的 “属性“(Attribute specifier sequence)
笔者最喜欢的C++属性就是[[nodiscard]]了,计划今天就在团队中推广开。因为许多开发者在调用一些可能失败的函数不检查返回值,导致代码鲁棒性较低。给一些重要函数加上[[nodiscard]]属性之后,编译器就能避免这种情况的发生,真是太有用了。如果向了解更多关于C++属性的知识,那么可以来cppreference看看。原创 2024-07-10 10:09:28 · 1456 阅读 · 0 评论 -
闲聊C++与面向对象思想
艾伦·凯曾说,“I made up the term object-oriented, and I can tell you I did not have C++ in mind.”(“我发明了术语‘面向对象’,可以告诉您我没有C++”)。今天看到这句话,激发了笔者写一篇文章聊聊C++与面向对象思想的关系。原创 2024-07-09 14:54:03 · 1338 阅读 · 0 评论 -
在编程活动中,比性能更重要东西是什么?
我们在进行技术问题讨论的时候,经常会涉及到这个问题。许多开发者对性能优化非常着迷,甚至许多人养成了“唯性能至上”的思维方式,甚至成为一种“政治正确”的事情,容易考虑许多非主流的技术方案来提高性能。本文希望说明一个观点:性能当然重要,但是还有比性能更重要的要素,在没有做好这些要素的适合,我们切勿对性能进行过早或过度的优化。原创 2024-07-08 11:13:37 · 692 阅读 · 0 评论 -
用C++思路写高质量的C++代码
C++以其强大的功能和复杂性而著称。然而,笔者在工作种发现,许多开发者在写C++代码时,会不自觉地沿用C语言的思维模式,这大大限制他们充分利用C++提供的强大功能写出高效安全的代码。因此,本文将通过几个常见的字符串操作示例,展示如何以C++的方式思考和编写代码,以及C++思维方式的核心价值。原创 2024-07-04 10:54:49 · 1088 阅读 · 0 评论 -
如何写出合格的C++构造和析构函数
笔者曾经在团队中发现有人在构造函数中读取文件配置,导致界面创建速度降低了一个数量级。由此引发笔者想讨论如何写一个合格的构造和析构函数文章的想法。原创 2024-07-03 15:50:31 · 947 阅读 · 0 评论 -
C++实现简化 QtBase(6):新增Timer定时器机制
在昨天的文章《》里,我们对EventLoop增加了Win32消息循环的支持。并支持post异步和延时任务。但是,还不支持timer的多次触发的定时器。今天我们一起来增加这个功能。原创 2024-07-03 14:33:20 · 1024 阅读 · 0 评论 -
C++实现简化 QtBase(5):通过IEventLoopHost扩展实现win32消息循环
今天,我们在之前的CEventLoop的实现之上,通过IEventLoopHost扩展,实现一个windows系统的主线程消息循环扩展,使得我们可以在主线程post task。原创 2024-07-02 15:17:36 · 705 阅读 · 0 评论 -
聊聊C++20的三向比较运算符 `<=>`
从这一个小小的三相比较运算符的引入,我们可以看到C++的复杂之处与细心之处,我们也能一窥现代C++的发展趋势,具体的复杂和细心在哪里体现?本文为您揭晓。原创 2024-07-02 10:45:27 · 1437 阅读 · 0 评论 -
C++实现简化 QtBase(4):增加简单实用的事件机制
前面的文章已经实现了许多QObject的功能了:C++实现一个简单的Qt信号槽机制C++实现简化版Qt信号槽机制(2):增加内存安全保障C++实现简化版Qt的QObject(3):增加父子关系、属性系统但是,Qt中还有一个关键的功能是事件系统。为了让我们的QObject也支持事件系统,我们可以设计一套简单实用的事件机制。设计事件循环事件系统离不开事件循环,截止到C++ 20标准库里没有一套官方的事件循环机制,可能是因为实现一个事件循环也不是什么难事吧。为了简化我们的事件循环机制,我们用到了一原创 2024-07-01 17:23:10 · 578 阅读 · 0 评论 -
C++实现简化版Qt的QObject(3):增加父子关系、属性系统
前几天写了文章:C++实现一个简单的Qt信号槽机制C++实现简化版Qt信号槽机制(2):增加内存安全保障之后感觉还不够过瘾,Qt中的QObject体系里还有不少功能特性没有实现。为了提高QObject的还原度,今天我们将父子关系、属性系统等功能也一并实现。接口设计首先,我们设计一下我们的接口。Qt的QObject类过于重,有的时候只用到部分功能的时候没必要引入额外的成员变量。因此我们将父子关系、属性系统这两部分单独抽离成为新的类。综合考虑下来,我们把支持静态、动态反射,信号槽的类改名为CObj原创 2024-07-01 15:41:52 · 887 阅读 · 0 评论 -
C++实现简化版Qt信号槽机制(2):增加内存安全保障
在上一篇文章中《C++实现一个简单的Qt信号槽机制》,我们基于前面的反射代码实现了信号槽的功能。但是上一篇的代码中没有对象生命周期管理的机制,如果在对象的生命周期结束后还存在未断开的信号和槽连接,那么信号触发时可能会尝试访问已经被析构的对象,从而引发内存访问异常。方案的确定在Qt框架中,QObject的析构函数,在对象销毁时会自动断开所有信号和槽的连接。从而避免出现这种情况。笔者考虑了一下,没有采取这种方案,因为:这会要求信号和槽两个对象互相存储双方的连接情况,在一定程度上浪费了内存。另一方面原创 2024-06-28 10:45:59 · 1553 阅读 · 0 评论 -
C++实现一个简单的Qt信号槽机制(1)
昨天写这个文章《深入探讨C++的高级反射机制(2):写个能用的反射库》的时候就在想,是不是也能在这套反射逻辑的基础上,实现一个类似Qt的信号槽机制?Qt信号槽机制简介所谓的Qt的信号槽(Signals and Slots)机制,是Qt框架中实现对象之间通信的一种方式。这是一个事件驱动程序中常见的设计模式。信号槽机制允许创建响应特定事件(如用户交互、数据变化等)的可重用组件。信号槽主要有以下核心概念组成:信号(Signals)信号是一个类成员函数的声明,它在类内部以 signals: 关键词标识。当原创 2024-06-27 16:23:33 · 1361 阅读 · 0 评论 -
系统性掌握C++17容器四件套:std::optional, std::any, std::variant, std::tuple
许多开发者分不清std::variant和std::any之间的区别,于是萌发了写一篇文章系统性介绍一下C++中这类容器的想法。原创 2024-06-27 10:24:11 · 1193 阅读 · 0 评论 -
深入探讨C++的高级反射机制(2):写个能用的反射库
在现代软件开发中,反射是一种强大的特性,它可以支持程序在运行时查询和调用对象的属性和方法。但是在C++中,没有内置的反射机制。我们可以通过一些巧妙的技术模拟反射的部分功能。我们这个简单反射库就称为refl吧。refl库是一个用C++编写的轻量级反射框架,它允许在编译时和运行时对对象的属性和方法进行查询和操作。这个库需要使用C++17编译器编译。其完整源码如下:#include <iostream>#include <tuple>#include <stdexcep原创 2024-06-26 18:24:54 · 1714 阅读 · 2 评论 -
深入探讨C++的高级反射机制
反射是一种编程语言能力,允许程序在运行时查询和操纵对象的类型信息。它广泛应用于对象序列化、远程过程调用、测试框架、和依赖注入等场景。由于C++语言本身的反射能力比较弱,因此C++生态种出现了许多有趣的反射库和实现思路。我们在本文一起探讨其中的奥秘。原创 2024-06-26 11:54:51 · 4226 阅读 · 0 评论 -
深入解析VC Runtime:什么是vcruntimeXXX.dll和api-ms-win-crt-runtime-X-X-X.dll?
总之,运行时库的 DLL 文件通常会随着安装 Visual Studio 或运行安装了 Visual Studio 开发的应用程序时被安装到系统中。如果应用程序使用动态链接库(DLL)而非静态链接库(LIB)版本的运行时库进行编译,则在运行时需要这些 DLL 文件。缺少这些文件可能会导致应用程序无法运行。通常情况下,安装对应版本的 Visual C++ Redistributable 可以提供这些必需的运行时库文件。但是最佳实践是在安装包中打包所依赖的运行时,可以减少很多用户反馈。原创 2024-06-24 15:10:25 · 1970 阅读 · 0 评论 -
运行时库链接方式实践指南(MT、MD、MTd、MDd)
通过本文系统性的介绍,相信你对运行时库的概念、特点。一致性的重要性有了更深的认识。原创 2024-06-24 10:29:27 · 2736 阅读 · 0 评论 -
C++:你用过MultiIndex容器吗?
作为C++开发者,我们对键值容器非常熟悉,例如std::set、std::map、std::unordered_map等。这些容器以其强大的功能和高效的性能,成为我们处理数据存储和检索任务时的得力助手。但是你用过多键容器(MultiIndex)吗?原创 2024-06-21 10:36:14 · 1111 阅读 · 0 评论 -
“锟斤拷,烫烫烫,屯屯屯”的由来
在程序开发过程中,调试是不可或缺的一环。调试不仅可以帮助开发者发现错误,还能提供程序运行时的内部状态信息。然而,在调试过程中,开发者有时会遇到一些奇怪的字符。这些乱码通常是由内存状态的特殊标记,或者字符集不匹配导致的。在本文中,我们将探讨这些乱码的由来,以及它们在程序开发中的含义。原创 2024-06-18 10:19:16 · 2011 阅读 · 0 评论 -
掌握现代C++的模板元编程类型检测技术
最近写代码恰好用到了C++模板元编程的类型检测能力,以前对其原理有个大概的印象,但随着C++11/C++17等新特性的加入,很多做法和以前不同了,借此机会重新梳理一下这方面的知识点。原创 2024-06-17 10:30:37 · 1219 阅读 · 0 评论 -
在C++中,NULL和nullptr有什么区别?
这两个定义导致了冲突,C++中的NULL如果和C语言一样也是(void *)0指针,而C++不允许void*隐式转换成其它指针类型,那NULL就无法表示空指针了。因此,使用 nullptr可以增加代码的清晰性,避免类型安全问题。即使在混合C++和C代码时,nullptr也提供了一个明确无误的空指针表示,达到兼容的目的。C++11 引入 nullptr 彻底解决了这些问题,提高语言的安全性、清晰性和现代性。在了解NULL和nullptr背后的故事之后,相信大家以后再也不会用NULL了。原创 2024-06-04 16:54:15 · 480 阅读 · 0 评论