C/C++
文章平均质量分 75
C/C++
Dontla
Life is short, I use AI.
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
C++嵌套锁Recursive Lock、Nested Lock使用场景(使用std::recursive_mutex替代std::mutex)(锁层次结构Local Hierarchy)递归锁
场景使用嵌套锁的原因示例类成员函数嵌套调用函数间相互调用且需要加锁成员函数A调用成员函数B,两者都需加锁递归函数递归调用中需要多次加锁遍历树结构时每次递归都需要加锁函数链式调用持有锁时调用其他需要锁的函数function_A调用function_B,两者都需加锁状态机或回调状态转换或回调中需要重复加锁状态A调用状态B,两者都需加锁分阶段处理多个阶段需要依次加锁分阶段处理共享资源,每个阶段需加锁在实际开发中,嵌套锁应谨慎使用,优先通过代码设计避免嵌套加锁的需求。原创 2025-07-16 12:08:19 · 976 阅读 · 0 评论 -
C++设计模式(GOF-23)——05 C++桥模式(Bridge)(将抽象部分与实现部分分离,使它们可以独立变化。通过组合(聚合)方式替代继承,避免多维度变化导致的类爆炸问题)
fill:#333;stroke:1;fill:none;important;important;important;important;important;important;important;important;important;important;important;important;important;important;important;important;11桥接模式通过组合替代继承,将抽象与实现分离,解决了多维度变化导致的复杂性问题。原创 2025-06-26 17:40:18 · 1227 阅读 · 0 评论 -
C++ Mermaid语法、Mermaid符号含义(Doxygen注释添加类图)(组合Composition、聚合Aggregation、关联Association)
A <|-- B->>通过 Mermaid 的语法和符号,开发者可以在 C++ 项目中清晰地表达逻辑关系、类结构和交互流程。原创 2025-06-26 16:01:54 · 1870 阅读 · 0 评论 -
C++设计模式(GOF-23)——04 C++装饰器模式(Decorator)(一个类同时继承和组合另一个类)解决类爆炸问题、模板装饰器
特性描述设计模式名称装饰器模式(Decorator Pattern)核心思想通过继承和组合动态扩展对象功能优点- 避免继承的类爆炸- 动态、灵活地添加功能- 符合开闭原则适用场景需要动态扩展对象功能,且功能可以独立组合。原创 2025-06-25 11:25:33 · 1080 阅读 · 0 评论 -
C++设计模式(GOF-23)——03 C++观察者模式(Observer / Event、发布-订阅模式、事件模式)
观察者模式(Observer Pattern)是一种行为型设计模式,用于建立对象间的一对多依赖关系。当一个对象(被观察者)状态发生变化时,所有依赖它的对象(观察者)都会自动收到通知并更新。这种模式通过解耦通知方与接收方,实现了系统的灵活性和可扩展性。特性传统实现观察者模式对象耦合度高低扩展性需修改现有代码支持开闭原则维护成本高低通知灵活性固定调用动态注册/注销适用场景复杂度简单场景复杂系统架构观察者模式通过接口抽象和行为封装,为复杂系统提供了优雅的通信解决方案。原创 2025-06-24 09:59:31 · 1438 阅读 · 0 评论 -
C++ std::remove()、std::remove_if()、std::remove_copy()(逻辑末尾)erase-remove、remove-erase idiom
在 C++ 中,并没有直接的remove()成员函数,但可以通过头文件中的算法实现类似功能。erase()erase()调用12423533new_end。原创 2025-06-23 15:46:16 · 697 阅读 · 0 评论 -
C++工厂模式的作用(工厂方法、Factory Method、Factory Pattern)
把"创建什么对象"的决策权从客户端转移到工厂,实现创建逻辑的集中管理和封装。这样代码更清晰、更容易维护,也更符合"开闭原则"(对扩展开放,对修改关闭)。原创 2025-06-20 09:38:23 · 542 阅读 · 0 评论 -
为什么在C++实现多态时,建议使用指针而非引用,且绝对不能用对象本身?(多态指针、多态引用)
主要原因涉及对象切片(slicing)、灵活性限制以及内存管理的复杂性。通过合理选择指针或引用,可以充分发挥多态的优势,同时避免对象切片和内存管理的陷阱。)动态分配和释放内存,适用于运行时不确定的对象生命周期。在C++中,实现多态时建议使用指针而非引用,且。:引用一旦初始化后,不能重新绑定到另一个对象。:指针可以存储在容器中,实现动态对象集合。:引用数组或容器无法动态管理对象集合。:指针可以随时指向不同的对象。原创 2025-06-19 14:48:42 · 820 阅读 · 0 评论 -
C++析构函数常见用法(默认析构函数、显式定义析构函数、私有析构函数、删除析构函数=delete、显式调用析构函数、显式默认析构函数=default、纯虚析构函数=0)
虚析构函数私有析构函数。原创 2025-06-18 17:06:15 · 1292 阅读 · 0 评论 -
C++ protected保护继承、保护方法(protected方法可以被派生类访问,不能被类外部直接访问)(C++ public公有继承、C++ private私有继承)
protected方法在C++中提供了一种中间的访问权限,允许派生类访问基类的特定逻辑,同时防止外部代码直接调用。这种机制在面向对象编程中非常有用,尤其是在需要继承和扩展功能的场景中。正确使用protected可以提高代码的封装性和可维护性。原创 2025-06-18 15:58:29 · 1005 阅读 · 0 评论 -
C++设计模式分类(GOF-23种设计模式)
创建一组相关或依赖的对象族。原创 2025-06-18 11:18:41 · 1352 阅读 · 0 评论 -
C++面向对象设计和面向接口设计区别(C++对象类、C++接口类)C++ Interfaces、C++接口与继承区别、依赖抽象而非具体实现,通过依赖注入解耦、依赖倒置原则DIP
特性面向对象设计面向接口设计核心对象和类接口和规范设计目标模拟现实世界,封装数据和行为解耦模块,定义统一契约实现方式类、继承、多态抽象类/纯虚类、接口实现灵活性固定类层次结构动态替换实现,灵活扩展典型应用场景单一功能模块开发多实现需求、插件化系统、跨平台适配C++ 中的实现使用class和struct使用纯虚类(面向对象设计是基础,强调数据和行为的聚合。面向接口设计是面向对象的延伸,强调规范与实现的分离。在 C++ 中,接口通常通过纯虚类实现,结合多态实现动态绑定。原创 2025-06-17 16:55:12 · 1825 阅读 · 0 评论 -
C++接口(C++ Interface、接口类型变量:指向抽象类的指针或引用)(通过抽象类和纯虚函数实现)(接口类命名以I开头,如:IDrawing)(虚析构函数:接口类的析构函数必须声明为虚函数)
在 C++ 中,接口的本质是抽象类纯虚函数= 0):没有具体实现的虚函数,强制派生类必须重写。抽象类:包含至少一个纯虚函数的类,不能被实例化(不能创建对象),只能被继承。public:// 纯虚函数virtual ~IDrawing() {} // 虚析构函数(必须)IDrawing是一个接口类,定义了draw()方法的规范。派生类必须实现draw()方法。在 C++ 中,接口是通过抽象类和纯虚函数实现的。原创 2025-06-17 16:28:10 · 1346 阅读 · 0 评论 -
C++面向对象设计原则7:封装变化点(Encapsulate Points of Variation)(将系统中可能发生变化部分与稳定部分分离,通过接口或抽象类隔离变化,降低模块间的耦合度)
封装变化点的核心是通过接口隔离变化,将稳定与变化分离。通过组合(如StablePart使用接口)替代继承,降低耦合。这一原则是设计模式(如策略模式、模板方法模式)的基础,也是实现开闭原则(对扩展开放,对修改关闭)的关键。原创 2025-06-17 15:47:21 · 959 阅读 · 0 评论 -
C++面向对象设计原则6:优先使用对象组合(Composition)(has-a),而不是类继承(Inheritance)(is-a);组合继承、C++组合
性能敏感的场景。原创 2025-06-17 13:33:55 · 1236 阅读 · 0 评论 -
C++面向对象设计原则4:里氏替换原则(Liskov Substitution Principle, LSP)is-a关系(子类对象必须能够替换父类对象,并且替换后程序行为不会发生改变)优先组合继承
LSP 是 C++ 中实现多态性和代码健壮性的基石。通过合理设计继承关系、接口约束以及组合替代继承,可以避免因子类行为不一致导致的程序错误。子类必须能够完全替代父类,且行为一致。原创 2025-06-16 18:04:55 · 1043 阅读 · 0 评论 -
C++move()含义(C++ move())C++移动语义(将左值转换为右值引用,触发移动语义,避免深拷贝,提升性能)
作用:无论传入的是左值还是右值, 都会将其转换为右值引用()。注意: 本身不执行任何移动操作,它只是通过类型转换为后续的移动构造函数或移动赋值运算符提供条件。2. 移动语义的核心思想移动语义是 C++11 引入的一种资源管理机制,其核心是:2. 触发移动构造函数/赋值运算符:移动构造函数或赋值运算符会“窃取”原对象的资源(如指针、句柄),并使原对象进入有效但未定义的状态。示例代码(自定义类):3. 资源转移后原对象的状态:原对象的资源被“窃取”后,其状态变为有效但未定义(例如原创 2025-06-16 13:37:53 · 1088 阅读 · 0 评论 -
C++ powershell不打印(C++powershellC++)最好用CMD,别用powershell
您遇到的问题在Windows开发环境中相当常见,特别是当程序输出包含中文字符或大量文本时。使用CMD是最简单可靠的解决方案!(但是我的似乎又没有问题)原创 2025-06-16 09:57:18 · 1020 阅读 · 0 评论 -
Windows使用winlibs安装MinGW-w64
注意调整优先级(上移到最上方,ps:我的会被之前装的Strawberry影响,调用到它的低版本g++)(我下载这个UCRT 64位最新版的。如果需要更完整的开发环境(如。在 Windows 上通过。架构,兼容性更好)。原创 2025-06-10 18:29:22 · 5349 阅读 · 0 评论 -
下载WinLibs时UCRT Runtime和MSVCRT Runtime(针对旧版本Windows)的区别
MSVCRT 是微软早期的 C 运行时库(MSVCRT.DLL),主要用于旧版 Windows 系统(如 Windows XP、Vista、7 等)。它是传统的 MinGW 工具链默认使用的 CRT。它是现代 MSVC(Visual Studio)和 MSYS2 工具链默认使用的 CRT。的区别主要在于底层使用的 C 运行时库(CRT)版本和兼容性。,并且希望使用现代 C/C++ 特性,推荐选择 UCRT 版本。例如,用 UCRT 编译的程序无法直接调用 MSVCRT 编译的 DLL,反之亦然。原创 2025-06-10 15:50:57 · 2835 阅读 · 0 评论 -
C++对象切片问题(C++ Object Slicing)(将派生类对象赋值给基类对象时,派生类特有的成员数据和行为丢失现象)(多态场景下,对象应通过指针或引用传递,避免值传递)多态破坏、破坏多态性
是一种常见的现象,指的是当将一个派生类对象赋值给基类对象(通过值传递或直接赋值)时,派生类对象中属于基类的部分会被复制到基类对象中,而派生类特有的成员数据和行为会被“切掉”(丢失)。即使派生类重写了虚函数,切片后对象的虚函数表指针会指向基类的虚函数表,导致多态调用失效。通过理解对象切片的机制和规避方法,可以更安全地使用C++的继承和多态特性。通过基类指针或引用操作派生类对象,可以避免复制,保留完整的派生类信息。切片后的对象行为不符合预期,例如调用错误的函数或访问错误的数据。派生类特有的成员变量(如。原创 2025-06-05 17:03:11 · 994 阅读 · 0 评论 -
C++虚函数表(虚表Virtual Table,简称vtable、VFT)(编译器为支持运行时多态(动态绑定)而自动生成的一种内部数据结构)虚函数指针vptr
虚函数表是C++实现。原创 2025-06-05 15:07:00 · 1549 阅读 · 0 评论 -
C++ vector容器存储对象和存储指针的区别(vector对象、vector指针)(存储指针时推荐使用智能指针)
通过以上对比,可以根据具体需求选择存储对象或指针。在现代 C++ 中,优先推荐使用智能指针来避免手动内存管理的风险。)时,存在显著差异,主要体现在。、自定义类实例)和指针(如。原创 2025-06-05 10:48:59 · 1121 阅读 · 0 评论 -
JavaScript闭包与C++静态变量:状态保持机制的对比(JS闭包、C++ static)(JS:普通局部变量、闭包变量)(C++:局部变量、静态局部变量)节流
JavaScript通过闭包的特性自然地实现了状态持久化,而C++则需要显式使用。关键字来实现相同效果。这是两种语言在设计理念和实现机制上的重要区别。原创 2025-04-04 18:24:21 · 538 阅读 · 0 评论 -
C++设计模式总结
根据具体需求灵活选用,切勿过度设计!原创 2025-03-08 23:07:35 · 1150 阅读 · 0 评论 -
程序语言的内存管理:垃圾回收GC(Java)、手动管理(C语言)与所有权机制(Rust)(手动内存管理、手动管理内存)
垃圾回收(Garbage Collection,GC)是一种自动内存管理技术。它的核心思想是在程序运行时,由垃圾回收器自动监控内存的使用情况,识别不再被引用的对象,并回收其占用的内存空间。// 错误:重复释放int* ptr;// 未分配内存free(ptr);// 错误:ptr未初始化。原创 2024-10-22 23:47:14 · 2031 阅读 · 0 评论 -
计算机系统中断机制介绍(中断机制提高了系统的响应能力和资源利用率,是实现多任务和实时控制的基础)(中断服务程序ISR、中断向量表IVT、中断控制器IC、中断延迟IL)(硬件中断与软件中断)计算机中断
中断(Interrupt)是一种计算机系统用于处理异步事件的机制。通过中断,外部设备或内部事件可以打断处理器当前的执行任务,转而执行相应的中断服务程序(ISR),以快速响应和处理紧急事件。中断机制提高了系统的响应能力和资源利用率,是实现多任务和实时控制的基础。中断机制作为现代计算机系统的重要组成部分,极大地提升了系统的响应能力和资源利用效率。通过合理的中断类型分类、中断优先级管理和高效的中断服务例程设计,能够实现高效的事件驱动系统。原创 2024-10-19 21:38:59 · 2584 阅读 · 0 评论 -
Rust引用与C++取地址、引用的区别(C++引用、Rust解引用、C++指针)
通过上述示例和解释,我们可以看到两种语言在内存管理、引用和取地址方面的不同哲学和实现方式。在程序设计语言的世界里,Rust和C++都是非常强大的工具,尤其在系统级编程中。本文将深入探讨Rust中的引用与C++中取地址和引用的不同之处,并通过示例展示它们的具体用法。C++允许程序员通过指针直接操作内存,这带来了极高的灵活性但也引入了许多潜在的风险,如野指针、内存泄漏等。Rust通过编译时的借用检查来保证引用的使用是安全的,而C++则依赖程序员手动确保指针的正确使用。)的引入为内存管理提供了更安全的工具。原创 2024-10-16 17:40:38 · 1273 阅读 · 0 评论 -
rust不允许在全局区定义普通变量!(Rust全局区)
Rust 采取了更为保守的策略,限制了全局变量的使用,以促进更安全、更可维护的代码编写。Rust 通常不允许在全局作用域中直接定义普通变量,这是为了减少错误和提高代码质量。这些变量在程序的整个生命周期内都存在,从程序开始执行时被初始化,到程序结束时被销毁。通过限制全局变量的使用,并要求在修改全局状态时采用显式的安全措施(如。代码块),Rust 力求减少常见的编程错误,如数据竞争和不确定的初始化顺序,这些在 C++ 中可能更难以控制。块中进行,这强调了潜在的风险和需要程序员显式处理的不安全操作。原创 2024-10-15 17:47:48 · 1253 阅读 · 0 评论 -
变量声明和变量定义的区别(声明与定义区别、定义与声明区别、声明定义区别、定义声明区别)
变量定义不仅声明了变量,还为它分配了内存空间。定义的存在意味着编译器在这一点将分配存储空间(如分配内存地址)。每个变量只能定义一次,但可以在其他地方声明多次。int x;// 声明并定义了变量 x。原创 2024-10-15 15:45:38 · 1257 阅读 · 0 评论 -
python内存管理与C++内存管理的区别与最佳实践(自动内存管理)(__enter__、__exit__)
虽然Python没有像unique_ptr那样的智能指针来管理内存,但其内置的垃圾回收机制和上下文管理器功能提供了一种高级且安全的方式来管理资源和内存。这反映了Python设计的高级抽象和易用性,以及它在资源管理上的自动化策略。如果你需要在Python中实现类似unique_ptr的功能,通常是通过结构化编程和合理使用上下文管理器来完成的。原创 2024-09-25 14:30:54 · 1876 阅读 · 0 评论 -
C++设备RS485控制程序波特率打印错乱,9600被打印成2580(9600十六进制0x2580)(std::cout << std::hex将std::cout的输出格式设置为16进制)IO操纵符
问题已解决:原因为std::cout原创 2024-09-05 15:11:52 · 1306 阅读 · 0 评论 -
C++IO操纵符(流操纵符、IO操作符、IO操纵符、I/O操纵符)(#include <iomanip>)改变流输出状态、流输出格式、打印格式、std::cout(以不同进制输出、对齐和填充)
在 C++ 编程中,输入输出操作是基本而重要的组成部分,涉及到数据的显示格式化以及用户交互的实现。C++ 通过一系列标准库中的 I/O 操纵符提供了强大的流控制能力,使得开发者可以精细地控制数据的输入输出格式。本文将深入探讨这些操纵符的种类、使用方法以及背后的工作原理。I/O 操纵符是一种用于修改输入输出流(如std::cinstd::cout)属性的工具。这些操纵符通过改变流的状态来影响后续的输入输出操作,例如改变输出的进制、对齐方式、精度等。原创 2024-09-05 15:09:53 · 1734 阅读 · 0 评论 -
C++ unique_ptr(智能指针,独占所有权)
在现代 C++(C++11 及以后版本)中,智能指针是管理动态分配内存的首选方式。unique_ptr是一种智能指针,它提供了对单一对象的独占所有权语义,确保无其他智能指针同时拥有同一原始指针。这种特性使得unique_ptr成为资源管理中保证资源释放和避免内存泄漏的强大工具。在某些情况下,可能需要对资源进行特殊的清理操作,unique_ptr支持自定义删除器,以满足这种需求。unique_ptr。原创 2024-09-03 15:59:27 · 1628 阅读 · 0 评论 -
C++枚举类(强类型枚举、强枚举)(枚举类与switch语句)
枚举类型(Enumerations)在C++中是一种用户定义的类型,它允许开发者为程序定义一个变量,这个变量限定在一组预定义的值之中。从C++11开始,C++引入了一种新的枚举类型,称为“枚举类”(或“强类型枚举”),它提供了更强的类型安全和更好的命名空间隔离。在使用现代C++进行项目开发时,适当使用枚举类不仅可以提高代码质量,还可以促进团队内部代码风格的一致性,降低维护成本。通过在枚举类的声明中指定类型,可以定义枚举值存储的底层类型。可以明确指定枚举类的底层类型,控制枚举类型的大小和性能。原创 2024-09-02 17:33:29 · 1735 阅读 · 0 评论 -
C++ noexcept关键字(用于指明函数是否会抛出异常。可以帮助编译器优化代码、提升性能,同时使函数设计意图更明确)
通过条件性的noexcept,C++ 程序员可以编写出更安全、更高效且易于维护的代码。这种技术利用了 C++ 强大的类型系统和模板特性,使得异常规格能够灵活地适应程序的具体需求。对于设计高质量库和API的开发者来说,理解并正确应用条件性noexcept是非常重要的。在决定是否将接口设计为noexcept时,要仔细考虑上述因素。正确地使用noexcept可以使你的代码更安全、更高效,同时提供更明确的合约。然而,滥用noexcept或在不恰当的情况下使用它可能会隐藏错误,导致更复杂的问题。原创 2024-09-02 11:11:04 · 1668 阅读 · 0 评论 -
C++面向对象单例模式禁止拷贝、禁止赋值操作(=delete)
总的来说,这种做法是对单例设计模式的一个强化,确保了类的全局控制和资源管理的安全性。对象赋值给另一个现有的对象。这是一种常见的做法,特别是在设计单例模式的类时。这行代码意味着你不能使用拷贝构造函数来创建一个。这些语句的作用是禁止拷贝和赋值操作对。这行代码阻止了将一个。原创 2024-08-13 16:04:47 · 1166 阅读 · 1 评论 -
c-periphery RS485串口库文档serial.md(serial.h)(非阻塞读)(VMIN、VTIME)
是两个非常重要的设置,它们控制了阻塞读取(blocking read)行为,尤其是在使用 termios(在 UNIX 和类 UNIX 系统中控制终端 I/O 特性的编程接口)配置串口时。流控制可以是软件实现的,也可以是硬件实现的,用于控制发送设备和接收设备之间的数据流,防止接收方的缓冲区溢出。这与阻塞读取(blocking read)形成对比,后者会在没有足够的数据可读时使调用线程暂停执行,直到有足够的数据可读或达到某个特定的条件(如超时或特定数量的数据已经可用)。设置定义了等待数据时的计时器。原创 2024-07-24 15:26:26 · 2075 阅读 · 0 评论 -
C++三种预定义标准流对象:std::cout标准输出、std::cerr标准错误输出、std::clog日志输出;(std::cerr非缓冲,输出立即显示)std::flush、std::endl
C++ 中的这三种标准流对象提供了与用户或其他系统交互的灵活和标准化方式。合理使用这些工具可以提高程序的健壮性、用户体验和维护性。理解和掌握这些流对象的特性和适用场景,是每个 C++ 程序员技能提升的重要一环。原创 2024-07-22 15:15:58 · 2098 阅读 · 0 评论 -
编译报错:visibility.h:30:10: fatal error: event2/event-config.h: No such file or directory(要包含编译后生成的头文件)
是 libevent 编译过程中生成的一个配置头文件,它包含了对系统特定环境的配置,例如可用的系统调用、编译器特性、库版本等。这些信息对于 libevent 的正确编译和运行是必要的,因为它根据这些配置来调整其行为,以适应不同的系统环境。这就是为什么需要在项目中引入这个文件。如果没有正确地引用这个头文件,编译器会缺少必要的环境配置信息,从而导致编译失败。原来这个文件是编译后才生成的!原创 2024-07-22 11:53:07 · 1123 阅读 · 0 评论
分享