C/C++
文章平均质量分 73
学习C++
Arcane Code
C++后端开发工程师
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
JsonRpc:手搓一个高性能Rpc服务(广播篇)
本文介绍了基于订阅-发布模式的广播系统设计。系统分为订阅者、话题和管理器三个核心组件:订阅者结构体维护订阅话题列表和客户端连接;话题结构体管理订阅者集合并提供消息发布功能;TopicManager类负责处理话题创建/删除、订阅/取消订阅等操作请求,并维护订阅者与话题的映射关系。系统采用互斥锁保证线程安全,支持类似B站UP主发布视频的广播机制,当话题更新时自动通知所有订阅者。该设计实现了高效的消息分发和动态订阅管理,适用于需要实时推送的场景。原创 2025-12-29 21:42:18 · 697 阅读 · 0 评论 -
JsonRpc:手搓一个高性能Rpc服务(应用篇)
本文摘要: 文章介绍了在JsonRpc基础上实现RPC应用功能的通信调度层设计。主要包含两个核心组件:Dispatcher负责根据消息类型分发处理请求,通过模板化的CallbackT类注册不同类型消息的处理函数;Requestor则处理个体消息的分发,支持异步和回调两种响应方式。Dispatcher使用unordered_map存储消息类型与处理函数的映射关系,Requestor通过RequestDescribe结构管理请求状态,提供阻塞和非阻塞两种发送模式。该设计实现了高性能RPC服务的消息调度机制。原创 2025-12-29 16:37:42 · 766 阅读 · 0 评论 -
JsonRpc:手搓一个高性能Rpc服务(底座篇)
JSON-RPC框架摘要 本文介绍了一个基于C++的JSON-RPC远程调用框架的实现。框架分为多个抽象层: 消息层:定义BaseMessage基类,包含消息ID、类型标识、序列化/反序列化等方法 连接层:BaseConnection类处理底层TCP连接,提供发送、关闭连接等功能 缓冲层:BaseBuffer类封装数据缓冲区操作 协议层:BaseProtocol类解决TCP粘包/半包问题,提供消息处理接口 服务层:包含BaseServer和BaseClient基类,分别实现服务端和客户端功能 框架采用多态设原创 2025-12-27 22:17:15 · 648 阅读 · 0 评论 -
C++:jieba库的安装使用保姆级教程
本文介绍了C++版中文分词库Jieba的安装与使用方法。主要内容包括:1)通过git克隆cppjieba项目;2)初始化并下载依赖子模块limonp;3)使用cmake和make编译生成可用库;4)测试验证库功能。最后给出了基础使用示例代码,展示如何加载词典文件并创建Jieba对象进行中文分词。文章针对初学者可能遇到的安装问题提供了详细步骤说明,帮助用户快速搭建中文分词环境。原创 2025-10-19 17:03:23 · 868 阅读 · 0 评论 -
c语言冒泡排序法
通过这样的方法每次比较虽然不能保证每个数都按从小到大排序好,但能使数组中最大的数排在最后,再缩短数组进行这样排序能使数组每个数都能按从小到大进行排序。原创 2024-01-19 16:33:13 · 463 阅读 · 1 评论 -
X型图形的打印
多组输入,一个整数(2~20),表示输出的行数,也表示组成“X”的反斜线和正斜线的长度。通过此条件再在此条件外创建一个for加for的循环嵌套。/部分当行和列相加等于scanf输入的值减去1打印*我们通过用printf和scanf来进行绘画。我我们可以创建一个与条件来进行判定。一个for表示行,一个for表示列。我们可以将此图形分开来进行绘画。\部分当行和列相等时进行打印*本题我们用“*”来打印X图形。其他情况一律打印空格。原创 2024-01-17 20:02:16 · 476 阅读 · 0 评论 -
C++namespace
非常简单,就是用namespace关键字定义一个范围,并且给这个范围取个名字,等下次你想调用你设置的这些个,变量,函数,什么个玩意,你怕跟别的冲突了你就在设置的时候给他划一块范围,等你想用的时候,你告诉系统什么范围的就不会和别的冲突了。看下面代码和解释int main()return 0;你看,上面这个打印rand就和系统的rand函数冲突了,系统不知道你要那个就报错了,但下面这个你告诉了系统范围的名称和rand,系统就知道你到底要找那个了。注意:1.namespace只能定义在全局。原创 2024-09-29 16:33:07 · 548 阅读 · 0 评论 -
C++类的定义和实例化对象和this指针
struct也可以像class差不多定义类,格式我不多说了直接看代码。原创 2024-10-03 16:39:01 · 2076 阅读 · 0 评论 -
C++的cin,cout,endl
在学c语言时我们学的是scanf和printf还有"\n",这些就对应了C++中的cin,cout,endl。cin,cout,endl存在于库函数<iostream>中我们要用他就需要引入这个库或者我们可以用using namespace std 来打开标准库用这三个函数但是在实际项目开发尽不建议用这个让我们看代码来对比一下用法这就是printf和scanf和“\n”的用法和cin,cout,endl的不同 endl其实就是换行,差不多相当于“\n”只不过它多了刷新缓冲区。原创 2024-09-29 17:09:17 · 595 阅读 · 0 评论 -
C++内联函数
分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错.要么就直接定义在头文件,定义和声明不要分开.原创 2024-10-02 22:49:50 · 326 阅读 · 0 评论 -
C++构造函数和析构函数
C++把类型分为内置类型和自定义类型,内置类型就是语言提供的原生数据类型,如int/char/double/指针等,自定义类型就是我们自己定义的类型比如用class和struct定义的类型。对于内置类型类中的默认构造函数可以将它初始化,但是对于自定义类型,类中的默认函数无法将它初始化,但在这个类中生成对象时,会自动调用自定义类型的类中的默认构造函数,但是如果这个自定义类型中的类没有默认构造函数那么编译器就会报错,默认构造函数又分为,无参构造函数,全缺省构造函数,我们不写编译器自动生成的构造函数,原创 2024-10-04 12:37:58 · 982 阅读 · 0 评论 -
C++引用
引用不初始化就会报错.原创 2024-10-02 20:27:16 · 520 阅读 · 0 评论 -
C++函数重载
C语言不支持在同一作用域中存在相同的函数名,但C++支持,但是要求这些同名函数的形参不同,可以是形参类型不同,或者个数不同,或者顺序不同,这三者必须要满足一点,否则编译报错,不构成函数重载,这两个Add编译虽然不会报错,但当我们调用Add()的时候编译器会报错,因为编译器不知道该调用那个Add的定义,存在歧义,这两个函数虽然构成重载函数但在使用的时候会发生错误。在main函数中,构建了两个int 变量和两个double变量,当这两组变量用Add函数运算的时候却调用了Add不同的定义。原创 2024-10-02 17:55:18 · 253 阅读 · 0 评论 -
C++nullptr
所以在这里NULL不是一个空指针而是一个值0,而nullptr是C++引入的一个关键字,它可以避免被类型转化,它永远是指针类型,而NULL可能会发生类型转化。按道理来说当函数重载时我们输入一个实参NULL我们想调用的时void Add(int*a)但是为什么C语言明明有NULL可以将指针置为空,C++还要引入nullptr呢。所以为了前面那种情况,我们在C++中最好用nullptr来定义空指针。其实理解nullptr很简单,它其实就是将一个指针置为空。其实简单理解C语言的NULL它其实是一个宏。原创 2024-10-02 23:08:36 · 353 阅读 · 0 评论 -
C++拷贝构造函数
拷贝构造函数的第一个参数必须是类类型对象的引用,如上图所示,const Date& d1是拷贝函数的第一个参数,拷贝函数也可以有多个参数,但第一个参数后面的参数必须都有缺省值。原创 2024-10-05 11:01:53 · 417 阅读 · 0 评论 -
C++缺省参数
缺省参数就是C++设计出来对C语言函数定义的优化对于上面Func()来说,在主函数中没有给参数但是在函数定义的时候有int a=0那么a就为0去运行函数,但如果给了参数Func(10),那么a就等于10,说白了就是你给我我就把原来有的丢掉用你给的,你要是不给我我就用我自己的。这就是缺省参数。原创 2024-09-29 17:38:12 · 362 阅读 · 0 评论 -
C++内存管理
要学习C++的内存管理,首先我们需要回顾一下C语言的内存管理,原创 2024-10-10 22:31:00 · 725 阅读 · 0 评论 -
C++多态的使用
在学习本章时我们一定要注意代码段我标明的注释。原创 2024-11-10 17:00:45 · 391 阅读 · 0 评论 -
C++仿函数
从使用方式上看,它能表现出类似函数的行为,但实际上它是一个对象,具备类的各种特性,比如可以拥有成员变量来保存状态等。总之,仿函数在 C++ 编程中是一种很实用的编程技巧,在实现灵活的代码逻辑、适配算法要求以及利用面向对象特性提升代码质量等方面都有着重要的应用。这样的方式来调用它,就如同调用一个常规的函数一样,最终得到 5 的平方值并输出。时都会更新这个变量的值,从而实现了对自身调用次数的统计,这是普通函数很难做到的。结构体组成的向量进行排序,展示了仿函数在自定义算法逻辑方面的灵活性。原创 2024-11-15 11:41:00 · 800 阅读 · 0 评论 -
C++内部类和匿名对象
内部类就是定义在一个类的内部的类,比如如上所示类BB定义在类AA中BB类虽然定义在AA类中,但BB实际上是存放在静态区中。看代码我们看到AA类的大小为8,意思就是AA类大小只包含它的两个int类型的成员,不包含BB类的大小。内部类默认是外部类的友元类代码解释运行结果用AA类中的BB类定义了B,B中的内置函数可以调用用AA类定义的A中private的成员如果将BB类定义在AA类中的private/protect中那么BB类就是AA类的专属类,其它地方都用不了,只有AA类中能使用。原创 2024-10-09 18:19:01 · 353 阅读 · 0 评论 -
C++copy memcpy strcpy
InputIt和OutputIt可以是迭代器类型也可以是指针类型first指向数组或者容器的第一个元素位置,last指向最后一个元素的下一个位置,遵循左闭右开原则,d_first指向复制产出对象第一个元素位置。原创 2024-11-14 15:30:23 · 315 阅读 · 0 评论 -
C++构造函数(初始化列表)
1.无论是否显示写初始化列表,每个类都有自己的初始化列表。2.无论是否在初始化列表显示初始化,每个成员变量都要走初始化列表。原创 2024-10-09 11:47:59 · 1076 阅读 · 0 评论 -
C++时间复杂度与空间复杂度
例如,对于一个排序算法,如果它的时间复杂度表示为 O(n^2),这意味着随着输入数据量(通常用n表示元素个数等输入规模相关的量)的增加,其运行时间大致按输入规模的平方量级增长。总之,在实际的 C++ 编程以及算法设计中,时间复杂度和空间复杂度是衡量算法优劣的重要指标,需要根据具体的应用场景(如对时间要求高还是对空间要求高)来选择合适的算法和数据结构,平衡两者之间的关系。这里强调的是额外存储空间,也就是除了输入数据本身所占空间之外,算法执行过程中临时开辟的空间。,所以空间复杂度是 O(n)。原创 2024-11-18 11:56:20 · 1511 阅读 · 0 评论 -
C++友元
上图的number1和number2被private给保护了起来,以至于print不能访问。有没有什么办法能让print(const Date& d1)能够访问number1和number2?让print()在类中声明,并且在前面加上关键字friend加上关键就说明这个函数是这个类的友元函数。运行结果通过这样的方式便能访问类private的成员变量友元函数并不属于类,只是一种声明权限,它可以访问类的private的成员。一个函数可以是多个类的友元函数。原创 2024-10-09 17:45:30 · 536 阅读 · 0 评论 -
C++vector(详解)
迭代器的作用就是让算法不用关心底层数据结构,其底层就是一个指针,或者是对指针进行封装,比如:vector的迭代器就是原生指针T*,因此迭代器失效就是迭代器对应的底层指针指向的那块空间被销毁了,使用了被释放的空间,因此程序会报错。那么访问时会报错,就算迭代器没有指向末尾的数据,在vs的环境下,会进行强制检查,意思就是当删除这个数据时,再次访问这个位置或是访问后面的位置时,即使没有指向末尾的数据,编译器仍然会报错。当我们不去控制vector对象的空间时,一直想其中添加数据那么vector是怎么增长的呢?原创 2024-10-27 15:46:52 · 756 阅读 · 0 评论 -
C++static成员
static修饰的成员函数称之为静态成员函数,静态成员函数虽然是成员函数,但是没有this指针。原创 2024-10-09 13:33:05 · 753 阅读 · 0 评论 -
C++虚函数表
每个包含虚函数的类的对象实例中,会隐含一个指针(通常称为虚指针,vptr),它指向所属类的虚函数表。在多继承场景下,情况会复杂一些,因为一个派生类有多个基类,每个基类如果有虚函数表,那派生类对象中就会有多个虚指针(每个基类对应一个虚指针,指向各自基类的虚函数表),同时还可能存在一个额外的属于派生类自己的虚函数表(如果派生类新增了虚函数的话)。虚函数表的核心作用就是支持多态性,也就是让通过基类指针或引用调用虚函数时,能够根据对象的实际类型(是基类对象还是派生类对象)来决定调用哪个类中重写后的虚函数版本。原创 2024-11-18 12:04:21 · 1551 阅读 · 1 评论 -
C++静态多态和动态多态
是指在编译阶段就能够确定要调用的函数版本,主要通过函数重载和模板(函数模板、类模板)来实现。这种多态性的实现依赖于编译器在编译时根据参数类型、数量等信息进行静态绑定(早绑定),也就是在程序运行之前就确定了具体要执行的代码逻辑。原创 2024-11-15 09:11:05 · 615 阅读 · 0 评论 -
C++继承(图文非常详细)
我们来看一下下面这串代码注意其中的两个类father 和 son我们可以发现son类定义的SN可以调用father的函数definity()如上图所示,这便是继承的格式。class 类名: 继承方式 继承的类名通过这样继承的方式我们可以想想一下,就是将father里面的内容全部让son可见,如果你觉得不好理解,你可以认为就是father里面的内容全部加进son里面,所以son就可以访问father里面的内容。原创 2024-11-09 13:49:45 · 900 阅读 · 0 评论 -
C++set(详解)
如果要将自定义类型的对象放入set中,需要为该类型定义比较规则(通常是重载运算符),因为set要根据这个比较规则来确定元素的顺序以及判断元素是否重复。// 重载 < 运算符,用于定义比较规则return 0;在上述代码中,通过重载运算符为Person类定义了比较规则,这样就可以将Person类型的对象存入set中,并且set能按照定义好的规则来管理这些对象(排序和去重等)。总之,C++ 中的set。原创 2024-11-17 16:22:34 · 6856 阅读 · 0 评论 -
C++类型转换
我们理解类型转换直接看下面的代码我们看上面的a是一个AA类型的,但是为什么8可以给它赋值并且不报错呢???我们看这个图,当8给a赋值时,编译器检测到8是一个int类型,便给8进行了类型转换,首先创建一个临时的AA类型,将8用来给这个类型赋值初始化,再将这个类型复制给a关于类型转换赋值,不单单可以只赋一个值,如果构造函数有两个参数,可以赋两个值,比如如果类中有两个重载的构造函数,比如一个构造函数有一个参数,而另一个构造函数有两个参数,那么会根据给的实参数量不同,而调用不同的构造函数。原创 2024-10-10 10:05:53 · 389 阅读 · 0 评论 -
C++模板初阶
为什么有模板C++要引入模板??如果我们要实现一个交换函数,比如那么当我要同时进行 double类型 ,float类型,int类型等各种类型之间的转换和不同类型之间的转换,那么我们是不是要写很多代码??比如那么有没有什么办法,让我写一个函数就够用呢???C++为我们提供了一个模板我们只要写一个函数,那么这个函数的形参类型会随着我们给的实参类型而变化我们给什么实参类型,这个形参就变成什么。那么这样是不是就方便了很多模板的格式返回值类型 函数名(参数列表){}原创 2024-10-11 20:09:03 · 1009 阅读 · 0 评论 -
C++string类(详解)
string是一个C++自己库里面定义的一个类类型,它的内部结构如下。它和c语言中的char类型差不多,也是用于定义字符串,但是C++引入string可以更好的对字符串进行操控,使用string必须包含#include头文件以及using namespace std;原创 2024-10-18 17:12:49 · 1058 阅读 · 0 评论 -
C++赋值运算符重载
运算符的定义要用到一个关键字operator,那么这个定义的格式就是operator+运算符号+(参数列表)+函数主体+返回值,如下图所示。原创 2024-10-05 14:51:23 · 1345 阅读 · 0 评论 -
C++重写和重定义和重载
概念重定义通常也叫隐藏,是指在派生类中重新定义了与基类中同名的非虚函数(普通函数),或者改变了基类中同名函数(无论是否虚函数)的参数列表等情况,使得派生类中的同名函数将基类中的同名函数隐藏了起来。这并非是为了实现多态,而是在派生类中重新定义了一个和基类有同名情况的函数而已。规则及特点只要同名就可能隐藏:只要派生类中有和基类同名的函数(无论参数是否相同),就会发生隐藏现象。如果想在派生类中访问被隐藏的基类同名函数,可以通过使用基类名加作用域限定符()来访问,例如。参数不同也隐藏。原创 2024-11-15 09:51:59 · 2613 阅读 · 0 评论 -
C++set的常用接口
中元素具有唯一性,所以元素要么存在(出现 1 次),要么不存在(出现 0 次),该函数返回值通常是 0 或 1,用于判断元素是否在。中第一个大于等于给定值的元素。常用于查找满足一定条件的元素区间起点等场景。容器丰富的操作功能,能满足各种涉及有序且唯一元素集合处理的编程需求。中,返回一个迭代器指向被查找的元素;若元素不存在,则返回指向。中的所有元素,将其变为一个空的。中第一个大于给定值的元素。所表示的位置)的迭代器。是否为空,为空则返回。返回一个迭代器,指向。返回一个迭代器,指向。原创 2024-11-17 16:31:45 · 668 阅读 · 0 评论 -
C++将整形数据转换为字符串
相对更灵活,适合在需要对多种类型数据进行复杂的格式化转换等场景;以上几种方法各有特点,可以根据实际的编程场景和需求来选择使用。则在一些需要兼容 C 风格代码或者特定格式化需求的情况下可以使用。最为简洁方便,在支持 C++11 及以上版本的代码中优先考虑;函数,将这个整数转换为字符串并存储在。在上述代码中,定义了一个整数变量。(表示格式化整数)的格式将整数。中提取出转换后的字符串存储到。变量中,最后输出该字符串。数组中,最后输出该字符串。变量,并输出这个字符串。这里定义了一个字符数组。原创 2024-11-19 18:58:10 · 2162 阅读 · 0 评论 -
C++模板进阶
在 C++ 编程中,分离编译(Separate Compilation)是一种常见的编译方式,它允许将程序的代码分散到多个源文件(.cpp文件)和头文件(.h或.hpp文件)中进行独立编译,最后再将各个编译单元生成的目标文件链接起来形成可执行程序。这样做的好处是便于代码的组织、维护以及团队协作开发等,不同的开发者可以并行地对不同的源文件进行开发和编译工作。例如,一个大型项目可以有多个.cpp文件分别实现不同的功能模块,对应的.h。原创 2024-11-19 19:25:33 · 840 阅读 · 0 评论 -
C语言:文件操作
文件是计算机用于存储数据的工具,我们计算机磁盘上的数据是混乱的,但是我们计算机系统通过文件的方式记录数据在磁盘上的位置来将数据整齐划分。原创 2025-05-04 21:25:08 · 815 阅读 · 0 评论 -
C++vector的常用接口及其介绍
在 C++ 中,vector是一个非常常用的动态数组容器,它定义在头文件中。以下是vector。原创 2025-01-03 14:31:15 · 507 阅读 · 0 评论
分享