- 博客(51)
- 收藏
- 关注
原创 Boost.Asio 异步写:为什么多次 async_write_some 会导致乱序,以及如何解决
只是注册回调,不是立即写入同时注册多个时,Boost.Asio 无法保证它们的执行顺序执行顺序的不确定性导致了最终发送顺序的不确定性Boost.Asio 的是异步的,多次调用会导致执行顺序不确定,从而造成发送数据乱序。解决方案使用发送队列,确保同一时刻只有一个活跃的写操作在单线程模型下不需要加锁在多线程模型下需要用互斥锁保护队列核心原则:串行化写操作,保证数据发送的顺序性。进阶优化对于高频小消息,考虑批量写入注意处理部分写入的情况避免递归调用导致的栈溢出。
2025-07-14 11:13:56
959
原创 Git 分支与远程仓库基础教学总结
远程仓库是托管代码的服务器版本,通常在 GitHub、Gitee 等平台。origin# 查看远程仓库 git remote -v # 重命名远程仓库 git remote rename origin old-origin # 删除远程仓库 git remote remove origin # 修改远程仓库地址 git remote set-url origin https://new-url.git命令作用是否修改代码git fetch拉取远程分支最新信息,不合并代码否git pull。
2025-07-02 21:41:20
1056
原创 搭建 C/C++_CMake_Boost_git 开发环境
完成以上步骤后,将在 Ubuntu 18.04 容器中拥有一个完整的 C++ 开发环境,支持 C++17、Boost 库、Git 和 CMake。您可以开始编写、编译和运行 C++ 项目。
2025-05-25 11:18:03
797
原创 docker 镜像完整生成指南
• 基础镜像 (~60MB) + Boost (~1GB) ≈ 最终镜像 1.1GB+• 每次环境变更建议升级标签(如。• 删除容器内的临时文件(如。▶ 方式二:上传到镜像仓库。▶ 从 .tar 文件加载。▶ 方式一:直接发送文件。生成(适合临时修改)生成(推荐,可复现)
2025-05-25 11:06:56
919
原创 Protobuf入门指南
Protocol Buffers(Protobuf)是Google开发的高效数据序列化工具,相比JSON/XML更紧凑快速。它支持跨语言使用,通过.proto文件定义强类型数据结构,并自动生成C++等语言的序列化代码。Protobuf支持嵌套消息、枚举、map等复杂类型,提供向后兼容性。示例展示了如何定义学生信息结构,包括基本字段、嵌套课程数据和年级枚举,并生成对应的C++类及访问方法。Protobuf特别适合网络传输和分布式系统,广泛应用于gRPC等场景。
2025-05-24 12:50:25
833
原创 可调用对象(5)-bind函数适配器
访问权限限制:类A的私有成员函数只能在类A的成员函数或友元函数/类中访问。std::bind不改变这一规则。绑定操作的上下文:使用std::bind绑定私有成员函数时,绑定操作必须在有权限的上下文中进行(如类A的成员函数或友元类)。类B的角色:类B无法直接访问类A的私有成员函数,但可以通过类A的公共接口或友元关系间接调用。现代C++建议:推荐使用 Lambda 表达式替代std::bind,因为其代码更简洁、易读,且访问控制规则一致。常见错误:在无权限的上下文中(如main。
2025-04-28 16:02:51
688
原创 可调用对象(4)-function可调用对象容器
/ 普通函数// 函数对象// 封装普通函数// 输出: Add: 7// 封装Lambda表达式// 输出: Subtract: 6// 封装函数对象// 输出: Multiply: 12return 0;
2025-04-28 15:58:54
203
原创 可调用对象(3)-Lambda表达式
Lambda表达式是C++11引入的一种轻量级函数对象,允许在代码中定义匿名函数。它们可以捕获周围的变量,具有更强的表达能力。Lambda表达式本质就是一个编译器帮你偷偷生成的仿函数(Functor)对象!Lambda表达式可以捕获类的成员变量和成员函数,使其在类的上下文中更加灵活。Lambda表达式与标准库算法紧密结合,提供了更简洁和直观的代码书写方式。Lambda是编译器自动帮你生成的匿名仿函数类,同样定义了。的类对象,只是一个是你手写,一个是编译器生成。仿函数是你自己写的一个类,里面定义了。
2025-04-28 14:57:39
442
原创 可调用对象(2)-仿函数
仿函数是通过定义一个类或结构体,并重载其调用运算符operator()来实现的。// 定义一个仿函数类int to_add;// 构造函数// 重载()运算符// 创建一个添加5的仿函数// 输出: 10 + 5 = 15return 0;
2025-04-28 14:04:49
424
原创 可调用对象(1)-函数指针
函数指针的定义涉及到函数的返回类型和参数列表。例如,定义一个指向返回int且接受两个int// 定义函数指针类型// 定义一个普通函数// 给函数指针赋值// 调用函数std::cout << "结果: " << result << std::endl;// 输出: 结果: 7return 0;
2025-04-28 13:57:01
283
原创 智能指针(删除器)之四
有时,默认的delete操作不适用于所有资源管理场景。此时,可以使用自定义删除器来指定资源释放的方式。例如,管理文件句柄、网络资源或自定义清理逻辑。当我们将资源批量存储到标准容器(如)中时,配合和自定义删除器使用可以大幅简化资源生命周期管理。比较点unique_ptrshared_ptr删除器类型模板参数构造函数参数默认删除器(调用 delete)(调用 delete)类型推导支持不支持 lambda 类型自动推导支持 lambda、函数指针等自动推导类型擦除不支持支持(存于控制块)
2025-04-24 10:25:38
810
原创 智能指针(weak_ptr )之三
是一种不拥有对象所有权的智能指针,用于观察但不影响对象的生命周期。主要用于解决shared_ptr之间的循环引用问题。主要特性非拥有所有权:不增加引用计数。可从shared_ptr生成:通过可以访问shared_ptr管理的对象。避免循环引用:适用于双向关联或观察者模式。
2025-04-23 20:21:07
590
原创 智能指针(shared_ptr)之二
是一种共享所有权的智能指针,允许多个shared_ptr实例共享对同一个对象的所有权。通过引用计数机制,管理资源的生命周期。主要特性共享所有权:多个shared_ptr可以指向同一个对象。引用计数:跟踪有多少shared_ptr实例指向同一对象。自动释放:当引用计数为0时,自动释放资源。用途作用允许类内部通过获取自身的shared_ptr解决问题避免导致的双重删除 / 崩溃依赖前提对象必须是由shared_ptr创建的,否则会抛异常。
2025-04-23 20:19:31
462
原创 智能指针(unique_ptr)之一
是一种独占所有权的智能指针,任何时刻只能有一个unique_ptr实例拥有对某个对象的所有权。不能被拷贝,只能被移动。主要特性独占所有权:确保资源在一个所有者下。轻量级:没有引用计数,开销小。自动释放:在指针销毁时自动释放资源。
2025-04-23 11:39:31
252
原创 1.C++ 动态内存分配对比:malloc/free VS new/delete以及 2.nullptr VS NULL 区别
场景推荐用法写 C++ 代码nullptr✅写 C 代码NULL✅写 C++ 98/03NULL(但注意类型风险)
2025-04-22 18:48:38
436
原创 理解 C++ 中的隐式构造及其危害
隐式构造是指编译器在某些情况下自动将一种类型转换为另一种类型,创建一个临时对象。例如,假设我们有一个Studentprivate:public:// 显式构造// 显示构造 如果编译器没有优化则调用拷贝构造,有的话就调用参数构造// 隐式构造// 正常调用// 隐式构造!return 0;//全部输出结果(假设编译器优化了拷贝) Student created!AliceBob在中,"Bob"是一个字符串字面量(),但期望一个Student对象。将"Bob"转换为。用这个。
2025-04-22 12:23:59
917
原创 内存对齐完全指南
对齐的根本目的:优化内存访问效率硬件要求:不同架构对对齐的要求不同,但都与内存访问机制相关填充规则:填充是为了让每个成员和整个结构体满足对齐要求性能影响:正确的对齐能显著提高内存访问性能,特别是在多线程环境中。
2025-04-21 11:58:38
835
原创 C++ 代码封装为动态链接库 (.so 文件) 并隐藏实现细节--两种方式
在 C++ 中,动态链接库(.so 文件)允许开发者将代码封装为可重用的模块,分发给其他程序使用。通过将实现细节隐藏在 .so 文件中,仅暴露必要的接口(函数或类方法),可以保护代码的知识产权,同时为用户提供简洁的调用方式。使用抽象基类或PIMPL 模式定义接口,隐藏实现。通过工厂函数创建和销毁对象。编译为 .so 文件并分发。提供用户友好的头文件和使用说明。通过抽象基类或PIMPL 模式,可以成功将 C++ 代码封装为 .so 文件,隐藏实现细节,提供清晰接口。
2025-04-20 16:56:13
430
原创 容器中的对象切片问题
std::list通常存储对象的副本,而非指向对象的指针。因此,当与继承结合使用时,可能导致问题,即仅存储基类部分,丢失派生类特有的信息。为了实现多态性,推荐使用指针或智能指针存储对象。
2025-04-20 16:52:55
137
原创 C++类成员函数 重写、覆盖与隐藏
特性重写 (Override)覆盖/隐藏 (Hide/Shadow)虚函数要求必须是virtual不需要签名要求必须完全一致可以不同多态性支持(动态绑定)不支持(静态绑定)调用行为由对象实际类型决定由指针/引用类型决定典型问题忘记virtual或签名不匹配意外隐藏父类函数解决方法使用override检查使用using恢复父类函数。
2025-04-20 16:50:46
455
原创 访问”和“初始化本质区别以及C++静态成员变量定义位置详解
你(Derived)住在爸妈家(Base),你可以用家里的冰箱(protected 成员),但盖房子(初始化)的时候得让你爸(Base 构造函数)去决定冰箱要不要装、装在哪里,你不能越权。✅ 这就像你住在你爸的房子里,屋子里东西你可以随便用,但你不能在房子建好之前,自己去改它的结构。,就可以直接访问它,因为继承关系允许子类访问。的东西 —— C++ 不允许这样。自己初始化它的成员,你只是告诉。构造函数,我直接改你。
2025-04-20 16:50:07
364
原创 函数指针小知识以及类内成员函数为何能访问同类私有成员
Lambda 类型可转换为函数指针原因无捕获[ ]✅ 可以编译器生成的是静态函数有捕获[=], [&]❌ 不可以生成的是闭包对象。
2025-04-20 16:47:49
249
原创 类中的函数返回&或值的选择以及错误解析,如:(Point operator=(Point &&other) )?(Point &operator=(Point &&other) )
是编译器在处理函数返回值时的一个概念性对象(不一定是代码中显式定义的变量,而是编译器内部的实现细节)。)是更常见和推荐的实现方式,因为它避免了不必要的拷贝,同时支持链式赋值。,可以理解为编译器处理返回值的“幕后英雄”,但在实际代码中不需要显式定义它。在 C++ 标准库和现代实践中,赋值运算符通常返回引用(两段代码的功能是一样的(移动赋值),但第二段(返回。),因为这符合惯例且效率更高。
2025-04-11 16:53:37
318
原创 C++类的详解(2)
当类A的成员变量是不可拷贝类型(如)时,A的默认拷贝构造函数会被隐式删除。要么禁止拷贝(推荐),要么自定义拷贝逻辑(通常不适用于移动语义(std::move)是处理这类资源的现代 C++ 推荐方式。必须显式编写析构函数,处理成员的结束逻辑。join()或detach()二选一,避免程序崩溃。禁用拷贝(因不可拷贝),但可支持移动语义。根据线程任务的必要性选择等待(join())或分离(detach()函数类型this类型是否能修改成员变量非 const 成员函数T* const✅ 可以。
2025-04-07 11:19:38
563
原创 原子操作 vs 互斥锁:原理、适用场景与选择指南
❌ 复杂数据结构(链表、树等)的操作。❌ 需要保证多个操作原子性的场景。❌ 多变量组成的复合结构体。✅ 标志位设置/清除 (使用默认seq_cst。
2025-04-07 11:10:04
334
原创 C++ I/O 流通俗指南
输出流的核心,用于将数据送到外部,依赖。流类型<iostream>:标准输入输出(cincoutcerr<fstream>:文件操作(ifstreamofstreamfstream<sstream>:字符串处理(格式化:用<iomanip>控制输出样式。自动管理:流对象析构时会自动关闭文件,无需手动清理(但可以显式关闭)。💡C++ 的 I/O 流就像“水管系统”,统一了各种数据处理方式,既灵活又强大!
2025-04-02 17:31:34
618
原创 snprintf 和 vsnprintf 函数使用指南
适用于直接格式化字符串的场景,不涉及可变参数列表。: 原示例中有拼写错误,使用了。适用于需要处理可变参数列表(
2025-04-02 09:43:04
424
原创 Socket函数详解:完整指南
socket()函数是构建网络应用的基础,掌握其参数和用法是网络编程的第一步。根据通信需求选择合适的domain、type和protocol组合,能够创建满足各种通信场景的socket,从进程间通信到跨互联网的应用都能胜任。
2025-03-30 19:43:40
1423
原创 Windows 和 Linux 操作系统架构对比以及交叉编译
Windows 和 Linux 在可执行文件格式和架构支持上有显著差异,但都支持多种处理器架构。跨平台开发需要深入理解架构差异、选择合适的编译工具和运行环境。
2025-03-25 15:31:47
1215
转载 const/const T&/const 指针/inline/constexpr(2)
inline关键字用于编译器将函数的调用,从而,提高程序执行效率。但inline只是,现代编译器会根据优化策略决定是否真正内联。👉 省去函数调用过程,提高运行速度。适用于短小频繁调用的函数适合代码少、执行频繁的小函数,比如:数学计算(max(a, b)、square(x))运算符重载❌ 不适合大函数,因为内联会导致代码膨胀(Code Bloat)。
2025-03-16 11:34:24
186
转载 const/const T&/const 指针/inline/constexpr(1)
const是 C++ 关键字,用于指示变量的值不可修改。通过使用const,可以提高代码的安全性与可读性,防止无意中修改变量的值。
2025-03-16 10:46:08
45
原创 左值引用和右值引用/move()函数/移动语义/完美转发
在C++中,左值(lvalue)和右值(rvalue)是表达式的两种基本分类,它们决定了表达式的结果在内存中的位置和状态。左值通常指的是具有持久状态的对象,它们有明确的内存地址,可以被多次赋值。而右值通常是临时的、没有持久状态的值,它们通常没有内存地址,或者其内存地址在表达式结束后就变得无效。C++11引入了右值引用(),用T&&表示,作为对左值引用(,用T&表示)的补充。这一特性极大地增强了C++的表达能力,特别是在资源管理和性能方面。
2025-02-26 14:59:59
855
原创 c/c++中的内存分配以及类的内存存储
指那些由编译器在需要的时候分配,不需要时自动清除的变量所在的储存区,如函数执行时,函数的形参以及函数内的局部变量分配在栈区,函数运行结束后,形参和局部变量去栈(自动释放)。栈内存分配运算内置与处理器的指令集中,效率高但是分配的内存空间有限。指哪些由程序员的储存区,如果程序员不释放这块内存,内存将一直被占用,直到程序运行结束由系统自动收回,c语言中使用malloc,free申请和释放空间。全局变量和静态变量的储存是放在一块的,其中初始化的全局变量和静态变量在一个区域,这块空间当程序运行结束后由系统释放。
2025-02-26 10:32:10
184
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人