执行顺序
静态变量: static
构造函数
泛型算法
#include <algorithm>
cyber/tools/cyber_recorder/spliter.cc
std::find(black_channels_.begin(), black_channels_.end(), channel_name) != black_channels_.end()
1.找到--返回指向第一个等于给定值的元素的迭代器
未找到--返回第二个参数来表示搜索失败==所以可以比较返回值和第二个参数来判断搜索是否成功
!= 搜索成功 == 搜索失败
2.
std::find(white_channels_.begin(), white_channels_.end(),chan.name()) != white_channels_.end() || white_channels_.empty()
std::find(white_channels_.begin(), white_channels_.end(), cbd.messages(idx).channel_name()) == white_channels_.end()
cyber/service_discovery/specific_manager/channel_manger.cc
特殊的迭代器--插入器 inserter
std::back_inserter 是 C++ 标准库中的一个函数模板,用于创建一个 std::back_insert_iterator 对象,从而方便地向容器的末尾插入元素
std::back_inserter() #include <iterator>
std::set_intersection
std::sort
auto 是一个占位符,函数名后 -> 紧跟的 int 才是真正的返回类型。
推导函数模板的返回类型,当然了前提是需要用到decltype说明符
lambda 需要返回值类型的时候 需要使用尾置返回值
std::bind()
100多个,精通10来个
find sort
cout search
std::set_intersection
all_of any_of none_of
迭代器类型
操作类型: 只读算法 写容器元素fill
功能:
示例: equal
时序图
C++类成员变量初始化顺序:
1) 基类的静态变量或全局变量
2) 派生类的静态变量或全局变量
3) 基类的成员变量
4) 派生类的成员变量
1.全局变量是何时完成初始化, 初始化的顺序是什么, 以及如何控制全局对象的初始化顺序
c++中全局变量初始化是在进入main函数之前完成的,也包括类的静态成员
2.static
声明为static的类成员称为类的静态成员,
数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见时,可将其定义为静态数据
用static修饰的 成员变量,称之为 静态成员变量;
用static修饰的 成员函数,称之为 静态成员函数
静态函数只能调静态成员,友元函数和静态函数都没有this指针。
static 被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间
被 static 修饰的变量属于类变量,可以通过类名.变量名直接引用 静态成员可以通过双冒号来使用即 <类名>::<静态成员名>
被 static 修饰的方法属于类方法,可以通过类名.方法名直接引用
因为静态成员函数属于整个类,在类实例化对象之前就已经分配空间了,而类的非静态成员必须在类实例化对象后才有内存空间,所以这个调用就出错了,
就好比没有声明一个变量却提前使用它一样。
静态资源是类初始化的时候加载的,而非静态资源是类实例化对象的时候加载的。 类的初始化早于类实例化对象
类的 静态成员变量 必须先初始化再使用
类的 静态成员函数 中不能引用非静态成员。
静态成员函数由于没有传递this 指针,所以静态成员函数只能访问static 成员,而不能访问非static 成员。this作用域是在类内部
类的 非静态成员函数 可以调用 静态成员函数,
类的static函数在类内声明、类外定义时,类内要写明static 类外则不能加static关键字
std::unique_ptr<>() ==
类内和类外不一样的地方 static inline
3.构造函数是与对象相关联的, 在调用构造函数之前需要为当前对象开辟内存, 需要将内存地址传入构造函数
初始化
对象工厂并不直接保存对象,而是对象的构造器,因为对象工厂不是对象池,是对象的生产者,允许不断地创建实例
4.线程
任务队列(Task Queue)
线程池(Thread Pool)
线程池最重要的方法就是负责向任务队列添加任务
并压入安全队列 m_queue.enqueue(warpper_func);
创建和使用线程池的基本步骤:
创建一个任务队列,用于存储待执行的任务。
在线程池中有一个阻塞队列,用于存放任务发布者发布的任务
创建一组线程,这些线程会从任务队列中获取任务并执行它们。
std::makei_unique<ThreadPool>() 线程池
将任务提交到任务队列中,由线程池的线程异步执行。
// 提交任务给线程池 enqueue 表示线程池部分 中的任务管道
接受一个函数指针或 Lambda表达式以及任何必要的参数,作为待执行的任务
线程池会不断地从任务队列中获取任务并执行,直到没有任务可执行。
线程池自动去做--已封装
5.宏定义
宏的本质是直接的文本替换
宏定义末尾不加分号;
宏定义中初始化了一个静态类,这是利用C++的静态初始化规则来确保在程序入口前便完成注册
宏展开
对应的宏展开
registerClass函数用来注册类,使用时想要一个类的类型参数是类名字符串,内部将一个闭包放入映射中,在创建时就会调用这个闭包来生成类
REGISTER_PRODUCT宏用来注册类,使用时只需要传入类名就可以,
他会利用静态变量初始化触发注册,符合全局作用域的语法规则
借助宏来实现自动注册,本质上是通过宏来定义了很多全局的静态变量,而这些静态变量仅仅是为了实现自动注册,并没有实际的意义
C++中,static const可以用来定义一个静态常量
类外
类外的 static 链接器不会再编译单元的作用域之外寻找该变量的定义
类内
6.lambda表达式
局部静态变量:
在C++中,你可以在类外定义一个局部静态变量,并通过一个立即调用的lambda表达式来初始化它。
这种方式类似于在函数内部使用局部静态变量,但在这里我们用它来初始化一个类的静态成员变量。
立即调用的lambda表达式:通过在lambda表达式后加上()来立即调用它,这样可以确保它在定义时执行并返回一个值。
这个值将被用来初始化const静态成员变量
使用lambda初始化的C++静态成员是一种在C++中初始化静态成员的方法
ABI
ABI 的功能需要
内核社区、 实现一个操作系统<硬件规范、汇编代码、数据结构、编程优化>
C 编译器(如 GCC 或 clang)、创建用户空间 C 库(通常是 glibc)的开发人员,
C 语言标准库 libc 提供了与 OS 交互的系统调用接口
以及按照 可执行与链接格式(ELF) 布局的二进制应用程序之间的合作努力
系统软件包括操作系统内核、驱动程序、工具软件、用户界面、软件库等
操作系统:
主要功能是向下管理CPU、内存和各种外设等硬件资源,并形成软件执行环境来向上管理和服务应用软件
操作系统需要知道如何与硬件打交道,如何给应用软件提供服务。
应用程序 其实是运行在由硬件、操作系统内核、运行时库、图形界面支持库等所包起来的一个 执行环境 (Execution Environment)
操作系统
处理器共享产生了程序间隔离的需求-内存保护机制
参考
C++实现工厂模式和注册宏 https://blog.csdn.net/z3363/article/details/145610167
C++11实现一个自动注册的工厂 https://www.cnblogs.com/qicosmos/p/5090159.html