
C/C++
XiaoH0_0
Fresh Meat
展开
-
[C/C++]代码查看
这里主要是大的架构学习,细节只能是一个一个去看。就是类比,和之前已经比较熟悉的架构去列表,找到相同,记录不同的地方去理解即可。如果有复杂的,可以自己来设计一下,然后和实际代码的流程做类比,看看是否理解的一样即可。大的架构一定是从整体来理解整个代码框架,不关心一些细节信息的。这点需要注意一下。主要目的是从全局角度有一个了解。任何一个有一定规模的,几十万行的系统,一定是包含了很多细节,很多小的trick的,如果一开始就将注意力放在这些细节上面,是一定会出问题的,对于这些细节的查看,大部分时间都是在浪费,而且.原创 2021-01-21 09:45:40 · 559 阅读 · 2 评论 -
[C/C++]变量作用域
编译器解析顺序,作用域:①C++主要是类,面向对象,所以从类的角度来看,通常,类也分为声明和定义,声明主要是一些成员变量、成员函数、而定义则是定义函数的具体内容。首先明确一个顺序,编译器在编译某个.o文件的时候,是先统一处理声明,然后再处理定义的顺序进行的,这也是为什么类的成员函数中可以非常方便的访问类内部的各个成员的原因,因为所有的声明在处理定义的时候都已经处理完毕并且记录下来了。②如果声明过程中,用到了之前的声明(比如声明一个函数,其返回值是之前的某一个typedef),这个时候还是按照顺序来解析原创 2021-01-12 08:00:43 · 256 阅读 · 0 评论 -
[C/C++]gtest+mockcpp,修改mockcpp以支持C++中类成员函数的mock
① 修改mockcpp的接口文件(追加一个宏),在mokc.h中追加MOCKER_CPP宏:#define MOCKER_CPP(api, TT) MOCKCPP_NS::mockAPI(#api, reinterpret_cast<TT>(api))② 使用例子:#ifndef SAMPLE_H#define SAMPLE_H#include <gtest/gtest.h>#include <mockcpp/mockcpp.hpp>#include &原创 2020-12-24 14:12:24 · 5909 阅读 · 8 评论 -
[C/C++]尽量减少使用shared_ptr
shared_ptr用于所有权的共享,是一种覆盖在普通指针上面的wrapper。进行了->符号重载,因此可以像普通指针一样使用。微观上的性能影响,和普通指针相比,主要是多了一层 函数调用,以及在share_ptr赋值的那一行需要进行原子操作的引用计数,除非很多线程同时操作,一般情况下,性能影响几乎可以忽略不计。所以性能并不是主要的问题,shared_ptr主要的问题是所有权共享 这种机制和所有权独享,会带来更多的并发编程隐患,多个线程同时持有一个对象,早就了过多的编码自由度,往往带来变量访问的条件竞争原创 2020-12-11 09:18:19 · 639 阅读 · 0 评论 -
[C/C++]dynamic_cast最好不要使用
dynamic_cast简介:dynamic_cast是将一个基类对象指针(或引用)转换到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理。RTTI简介:RTTI(Run-Time Type Identification)是面向对象程序设计中一种重要的技术。C++中的指针或引用(Reference)本身的类型,可能与它实际代表(指向或引用)的类型并不一致。有时我们需要将一个多态指针转换为其实际指向对象的类型,就需要知道运行时的类型信息,这就产生了运行时类型识别的要原创 2020-12-08 10:00:34 · 1203 阅读 · 0 评论 -
[C++] noexcept关键字简介
简介:noexcept关键字,说明函数不会抛出任何异常,如果该函数在运行过程中违反了noexcept约定,试图抛出异常,C++会调用std::terminate函数终止程序运行。noexcept优缺点:优点:1.调用noexcept函数时不需要记录exception handler,所以编译器有更高的自由度,提升了生成更加高效的执行代码的可能性;2.确保代码中不使用throw和try…catch的方式在函数执行过程中抛出异常。而是通过函数返回值和出参的方式返回异常,在外部显式的处理异常..原创 2020-12-04 15:39:23 · 3561 阅读 · 0 评论 -
[C/C++]so加载和卸载的时候运行函数:
宏调用:INITIALIZER(FunctionName) {}#define INITIALIZER(f) \ static void f(void) __attribute__((constructor)); \ static void f(void)#define DEINITIALIZER(f) \ static void f(void) __attribute__((destructor)); \ static void f(void)#endif原创 2020-09-25 14:33:33 · 931 阅读 · 0 评论 -
[LINUX]find排除某个目录
查找当前目录和子目录中.cpp后缀的文件,且排除当前目录下的except目录find ./ './except*' -a -prune -o -name *.cpp -print原创 2020-09-17 13:34:49 · 1613 阅读 · 0 评论 -
[MAKE]链接时依赖的so not found
链接时,依赖于a.so,该so可以找到,但是a.so又依赖于b.so,b.so找不到时,ld会报warning:b.so needed by a.so not found.此时可以设置rpath-link选项去除该warning:-Wl,-rpath-link,/xx/xxx/lib原创 2020-09-14 13:56:24 · 494 阅读 · 0 评论 -
[C/C++]交叉编译
交叉编译,即在某一个基础平台上编译另一个平台能够运行的软件,如在x86平台编译arm程序,交叉编译的前提是存在交叉编译SDK,里面包含了适用于目标平台的编译工具链、系统库等交叉编译必备的依赖文件,编译时通过指定sysroot来重定向访问sdk中的文件;编译过程涉及到编译、链接:编译:交叉编译的编译器是特别指定的,通过CMake设置交叉编译工具链文件,在编译时会根据环境变量,自动调用所需编译器;库的头文件路径,交叉编译器有自己的基础库头文件路径,通过指定sysroot参数,指向sdk所在路..原创 2020-09-04 15:09:34 · 1937 阅读 · 1 评论 -
[YOCTO]找不到en_US.utf8
① 运行以下命令查看是否存在en_US.utf8:locale -a② 不存在则进行安装:apt-get updateapt-get install locales-all原创 2020-08-31 14:21:11 · 1358 阅读 · 1 评论 -
[C/C++]插件模式开发
插件模式类似于hook,不改变原有软件的流程,将新的功能模块打包成动态库;将新增插件配置到插件库配置文件中,包括so库,入口函数,触发器等信息;重启主程序,或触发重加载流程,主程序读取插件库,读取对应的so,从而集成插件功能;插件使用:通过远程消息触发,或命令行触发插件功能;插件更新:直接更新插件动态库和对应的so文件,重新加载插件库;插件模式的好处:动态更新,模块之间相独立,可扩展性强;...原创 2020-08-27 15:33:50 · 935 阅读 · 0 评论 -
[C/C++]其他类型转换成字符串
#include <sstream>#include <string>#include <vector>template <typename T>std::string toString(T item){ std::stringstream buffer; buffer << item; return buffer.str();}使用:int i = 1998;string strI = toStri原创 2020-08-26 13:49:09 · 403 阅读 · 0 评论 -
[C/C++]运行时动态生成代码
使用libtcc在运行时编译生成动态库,源码中需要有一个hook点,专门用于加载和执行动态生成的函数,调用dlopen函数加载动态库,dlsym找到函数地址,实现运行时动态执行生成的函数功能;使用tinyfilter,运行时读取动态生成的配置文件,根据配置文件的蓝图连接各个类型的tinyfilter,生成pipeline tree,从而实现动态生成函数执行逻辑的功能,这种方式的限制在于tinyfilter的功能,若tinyfilter不具有的功能,无法动态执行,不如前者自由;动态生成函数的使用场景非常.原创 2020-08-26 11:34:16 · 1694 阅读 · 0 评论 -
[C/C++]状态机设计
定义消息队列,用来缓存来不及处理的消息;定义预处理,用来判断消息的有效性、是否需要缓存、延后处理等,预处理和状态机当前的状态无关;定义主处理,主处理应该是一个状态机栈,栈顶是当前的状态机上下文,其中存储当前状态机的状态等- 信息,根据消息ID,在当前状态机的对应状态处理表中,查找是否有消息ID对应的处理函数,如果有,则进入处理函数进行处理,如果没有,则消息将被丢弃(或者在预处理判断后进行缓存);定义后处理,当一层状态机退栈后,执行一次后处理,包括处理所有的缓存消息、内部消息(状态机可以自己给自己发内.原创 2020-08-25 09:44:00 · 518 阅读 · 0 评论 -
[C/C++]静态检查工具oclint
安装依赖:apt-get install libtinfo-dev;直接从oclint的git仓库克隆oc-lint项目到本地;cd到oclint-script目录运行./make;安装完毕后,到上一级目录查找一下oclint二进制,一般在release文件夹中,设置到系统路径中即可;oclint需要指定到具体的源文件:oclint --report-type=json -o oclint.json -p ./ /home/xxxx/*.cpp指定了报告类型、报告的输出文件、-p是com.原创 2020-08-24 15:49:50 · 401 阅读 · 0 评论 -
[GCC]依据头文件目录关闭编译告警
gcc -Ixxx // 通常的目录包含,这些目录下的头文件会产生告警gcc -Isystem // 系统头文件目录,这些目录下的头文件不会产生告警cmake中可以在target_include_directories()指定SYSTEM属性即可。原创 2020-08-24 13:10:00 · 563 阅读 · 0 评论 -
[GCC]部分屏蔽告警
使用GCC自带的屏蔽宏(ignore):这种方式比较重量级#pragma GCC diagnostic push#pragma GCC diagnostic ignored "-Wwrite-strings"#pragma GCC diagnostic ignored "-Wunused-variable"#pragma GCC diagnostic pop可以设置一组宏来简化使用:#define dw(N) _Pragma("GCC diagnostic push"); \ .原创 2020-08-18 13:26:56 · 1349 阅读 · 0 评论 -
[C/C++]CMake基础设置
内置变量:和环境变量不同,cmake有一些内置固定名称的变量,比如CMAKE_CURRENT_SOURCE_DIR就是当前的CMakeList.txt所在的路径,内置变量使用${内置名称}的方式引用,如果要设置,使用set汉函数进行,set(inner_name “value”),cmake中有很多的内置变量可以自行根据使用去查看;环境变量:环境变量即linux中的环境变量,使用${ENV(名称)}的方式引用环境变量的数值,内置变量和环境变量都可以在同一次的cmake编译中第归的传递下去,即只需要在头部.原创 2020-07-09 21:15:27 · 213 阅读 · 0 评论 -
[C/C++]定时器相关
【计算机定时器相关】timer定时器的底层实现逻辑:时间轮。在linux内部,如何得到时间节奏的呢?答案是高精度的硬件,如果有一个硬件能够保证每次过一个绝对固定的时间,一模一样的时间,触发一次中断(tick),那么其实计算机就能够实现基于这个中断作为最高精度的定时器了。所以定时器的实现实际上还是依赖于硬件。另外,linux中有几种定时器的必须实现的场景:①tick:有些tick间隔内必须要去做的事情;②获得当前的时间,这个也是很多应用层的软件的需要的,但是tick硬件怎么能够转成当前的时间呢?答案是原创 2020-07-06 21:14:36 · 205 阅读 · 0 评论 -
[C/C++]覆盖与隐藏
①类的名字查询逻辑:前后有继承关系的类,其作用域实际上是嵌套的,即虽然我们写成两个类,父类和子类,看上去好像是分离的,实际上,他们就是另一种我们常见的类的关系,就是嵌套类。当我们申请了一个子类的对象,调用其中的一个继承而来的公有函数的时候,编译器实际上是首先在子类中根据函数的名称进行查找,查找不到的话,再到他的上一层的作用域中进行查找的,这样一直向上嵌套的查找一直到基类,所以基于这种查找逻辑就可能引发一个问题,就是按照名字来查找,而完全不去看后面的参数列表的话,那么当在子类和父类都定义相同名字,而不同参数.原创 2020-07-01 20:13:42 · 467 阅读 · 1 评论 -
[C]定义临时结构体变量
通常用于测试等quick code场景struct { char buff[6];} a { "hello" };原创 2020-06-30 20:07:45 · 727 阅读 · 0 评论 -
[C]定义临时结构体变量
通常用于测试等quick code场景struct { char buff[6];} a { "hello" };原创 2020-06-29 19:52:27 · 1333 阅读 · 0 评论 -
[C]字符串连接特性
字符串可以直接连接printf("aaa\n" "bbb\n");等价于printf("aaa\nbbb\n");原创 2020-06-23 19:58:42 · 196 阅读 · 0 评论 -
[C]__always_inline宏
__always_inline作用类似于inline,告诉编译器,进行强制内联的修饰符。原创 2020-06-22 19:47:54 · 633 阅读 · 0 评论 -
[C/C++]goto语句的使用场景
1.用于需要跳出多层循环for () { for () { goto err; }}err:2.用于异常处理,通常可以统一处理错误信息。if () { goto err;}err:原创 2020-06-18 20:38:51 · 360 阅读 · 0 评论 -
[LINUX]preload hook dlopen
preload hook中需要通过dlopen打开对应的so,查找旧函数地址以便后续调用;如果需要hook dlopen这个函数,就会出现死循环的情况,因为dlopen中需要调用自身来加载so,获取dlopen函数地址;可以使用dlmopen代替dlopen加载so的功能,这样dlopen函数也可以被顺利hook了;...原创 2020-04-20 19:56:05 · 496 阅读 · 0 评论 -
[LINUX]判断一个进程号是否存在?
检查/proc/{id}/exe这个文件是否存在;可以用access或者stat等系统调用实现;if (access("/proc/12345/exe", 0) != -1) { // 进程存在}原创 2020-04-17 20:08:17 · 1418 阅读 · 0 评论 -
[C/C++]priority_queue自定义结构体和比较函数
// priority_queue 自定义结构体和比较函数struct Node { int value1; int value2;};bool operater<(const Node& a, const Node& b){ return (a.value1 < b.value1);}priority_queue<Node> q;...原创 2020-04-11 14:35:36 · 1164 阅读 · 0 评论 -
[Algo]最短路径搜索
- 从有向带权的图中获取某个源点到剩余的其他节点的最短路径的算法,权表示的是路径长度。- 维护一个长度数组v[n],n就是节点个数,每个数组都存储源点到对应的节点的长度,一开始初始化的时候,由于都不知道,所以都初始化成无穷大,然后开始算法:- 首先是源点到源点的,初始化成0。- 然后看所有和源点相连的所有其他节点路径,这些路径是已知的了,发现比数组中当前的无穷大小,所以更新到数组中,即...原创 2020-04-09 20:38:16 · 198 阅读 · 0 评论 -
[C/C++]构造函数初始化
构造函数:①编码过程中倡导:函数功能尽量单一,尽量多的扇入,合理的扇出。构造函数也是一样的,构造函数的最重要的功能,就是初始化,所有和初始化有关的,都可以放在构造函数中,比如类内部成员的初始化等。②初始化方式:其实有三种方式初始化:(1)在声明成员变量的时候直接初始化,这种方式过去并不是十分的习惯,但其实是一个不错的方式,如果一个成员的初始值是确定的,在构造函数中不用去改变的,那么可以...原创 2020-03-29 20:08:52 · 2789 阅读 · 0 评论 -
[C/C++]switch语句的default语句必须放在最后吗?
switch语句的default语句必须放在最后吗?是否可以放在开头?因为有时候,default可能不是特别重点关注的分枝,可能一开始先想要写掉,后面再逐渐的添加各种case条件分枝,也方便后面case部分的拓展:答案是肯定的,编译器会在编译过程中自动的优先判断case,最后再去看default。只是有一些case可能想要部分进入default的,放在前面可能就不那么的直观了。但顺序是没有要求...原创 2020-02-18 20:34:46 · 7524 阅读 · 0 评论 -
[C/C++]decltype和auto区别
auto是根据在定义的时候的”初始值“,来推断类型。而decltype是根据操作数来推断类型的。即delctype后面括号中的表达式,是不需要计算值的,有表达式也不会实际去赋值的。两者区别显而易见,就是可以有初始值,那么用auto,如果没有,那么从表达式操作数也可以进行推断,这个时候使用decltype;【注意】:auto和decltype主要是用于一些很难推断出类型的,比如模板类中使用。实际...原创 2020-01-18 19:57:46 · 211 阅读 · 0 评论 -
[C/C++]Virtual基类
和Inline有相同点,Inline就是编译的时候将函数直接展开来,不使用链接方式。Virtual也是影响编译和链接的一种修饰符。Virtual基类:(虚拟继承)用Virtual修饰类,派生类到基类存在多条路线时(多个继承脉络或者途径),一个这种派生类的对象实例化将包含多个基类对象。用Virtual来避免产生多个基类的对象在多继承下,虚继承就是为了解决菱形继承中,B,C都继承了A,D继承了B,...原创 2020-01-12 19:44:55 · 496 阅读 · 0 评论 -
[C/C++]拷贝构造和拷贝赋值函数的删除场景
对于支持多实例的类不应该删除拷贝构造等默认函数的原因,即为什么需要删除拷贝构造和析构等函数?是否一般就是用于单例类的时候,需要删除,支持多实例的话不需要进行删除?拷贝构造主要是两个问题,一个是浅拷贝,即有指针成员的情况下,会在析构的时候释放两次。另一个是基类拷贝问题,如果有基类,会调用基类拷贝构造函数来调用基类,但是如果自定义了拷贝构造函数,就只会调用基类的构造函数,所以如果写了子类的拷贝构造函...原创 2020-01-08 20:39:19 · 1257 阅读 · 1 评论 -
[C/C++]unique_ptr使用
unique_ptr:和shared_ptr相对应,unique_ptr就是头同时只能有一个对象拥有指针的所有权的意思,大部分操作和shared_ptr是一致的,比如解引用等,但是也有很多区别,①释放所有权:unique_ptr有所有权的转义概念,因此,不能使用直接的=进行拷贝赋值,是不允许的,要将一个unique_ptr移动给另一个unique_ptr就需要使用release()函数进行...原创 2020-01-03 21:56:44 · 365 阅读 · 0 评论 -
[C/C++]使用模板函数减少函数入参
使用模板函数减少函数入参,主要用于空间换取性能:enum kind { apple, orange};void func(int a, int b, enum type);此时函数有3个入参,由于枚举类型是有限的数量,因此可以设置一个模板函数,这样可以少传入一个参数template <typename kind k>void func(int a, int b);...原创 2020-01-01 10:24:29 · 401 阅读 · 0 评论 -
[WINDOWS]在windows上编译使用cmake的工程
在windows上编译使用cmake的工程1.进入CmakeList.txt所在的文件夹,新建一个目录build,并进入该目录mkdir buildcd build2.运行cmake命令进行解析,检查依赖项(需要安装VS Build Tools)cmake ..3.运行编译命令即可自动开始编译,这里的Target与2步骤中生成的vcxproj后缀的文件保持同名cmak...原创 2019-12-29 08:36:44 · 2088 阅读 · 1 评论 -
[C/C++]问题分析
代码问题分析的常用方法:①对比法:前提:有问题相关的异常信息,和同一个流程下的正常信息,通过对比的方式找到正常信息和异常信息的区别,从这个“区别”点入手,分析问题产生的原因以及对应的解决方法。②异常点分析法:前提是有问题相关的异常信息,并且知道异常点发生的位置,通过查看异常时间点附近的log的方式来分析异常问题。③如果认为问题的异常信息不足以判断问题的原因(①和②都用不了),则只能通过添加...原创 2019-12-27 22:35:54 · 155 阅读 · 0 评论 -
[LINUX]memory order简介
①C++内存中的存储,其实是以byte方式进行存储的。(一些大的数据可以能使连续的多个byte),而每个byte是有一个固定的地址(虚拟地址),类似于门牌号的作用,而在byte中更小的单位是bit。可以用std::numeric_limits::digits进行访问。②内存地址:Memory Location: 一个用于存放不同类型的数据的空间。可能是一定长度的比特位,或者是特定的类型。③线...原创 2019-12-25 22:03:32 · 535 阅读 · 0 评论