# Wily的CPP学习笔记
> `2022/06/27`
> 1. 标准库 bind 函数
> private:
void timer_callback()
{
auto message = std_msgs::msg::String();
message.data = "Hello, world! " + std::to_string(count_++);
RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
publisher_->publish(message);
}
std::bind()
C++的类成员函数不能像普通函数那样用于回调,因为每个成员函数都需要有`一个对象实例`去调用它。 通常情况下,要实现成员函数作为回调函数:一种过去常用的方法就是把该成员函数设计为静态成员函数(因为类的成员函数需要隐含的this指针 而回调函数没有办法提供),但这样做有一个缺点,就是会破坏类的结构性,因为静态成员函数只能访问该类的静态成员变量和静态成员函数,不能访问非静态的,要解决这个问题,可以`把对象实例的指针或引用做为参数传给它`。 后面就可以靠这个对象实例的指针或引用访问非静态成员函数。另一种办法就是使用std::bind和std::function结合实现回调技术。
> `2022/06/29`
> 1. 关键字explicit
编译器是允许进行隐式转换(implicit conversion)的,如果现在在构造函数的前面加个关键字explicit,它的意思就是要告诉编译器,这个隐式转换不会再被允许了,只有当你有一个好的理由允许构造函数隐式转换,不然的话请把它们都声明为explicit,因为隐式转换容易导致错误,而这个错误往往不容易察觉。
> 2. `usleep`函数
能把线程挂起一段时间, 单位是微秒(千分之一毫秒)。本函数可暂时使程序停止执行。参数 micro_seconds 为要暂停的微秒数(us)。
头文件: `unistd.h`
语法: `void usleep(int micro_seconds);`
返回值: 无
> `2022/07/06`CLI 真的cool
> 1. 编译过程
C++ 在linux下使用gcc编译器,该款编译器可以用于编译Go,Fortran,Ada,D等后端语言,编译过程如下:
1. Pre-Processing //.i文件`文件展开,如纳入头文件`
> g++ -E test.cpp -o test.i
2. Compiling //.s文件`编译之后是汇编语言`
> g++ -S test.i -o test.s
3. Assembling //.o文件`编译之后是机器语言`
> g++ -c test.s -o test.o
4. Linking //bin`编译之后是可执行文件`
>g++ test.o -o test
5. 通常我们只用一个步骤:
`g++ test.cpp -o test`
> 2. g++ 重要的编译参数
-g 编译带有调试信息的可执行文件
`-O[n] n选择1-3 有优化代码的作用`
-l 和-L 指定库文件|制定库文件路径(用于自己写的库)
-I 指定头文件搜索目录(头文件不在/usr/include时候)
-Wall 打印警告信息
-w 关闭警告信息
`-std=c++11 设置编译标准`
-o 制定输出文件名字
`-D 定义宏(通常在代码中定义DEBUG的宏)`
`‘’‘ 和#ifdef DEBUG #endif搭配使用 ’‘’`
> 3. 生成库文件并且编译
1. 静态库链接
# 汇编,生成swap.o文件,名称缺省
g++ swap.cpp -c -I../include
生成静态库libswap.a
ar rs libswap.a swap.o
编译
g++ main.cpp -Iinclude -Lsrc -lswap -o staticmain
2. 动态库链接
# 直接生成
g++ swap.cpp -I../include -fPIC -shared -o libswap.so
该命令相当于:
g++ swap.cpp -I../include -c -fPIC
g++ -shared -o libswap.so swap.o
编译
g++ main.cpp -Iinclude -Lsrc -lswap -o dynamicmain
> 4. GDB调试器
vscode是使用GDN调试器来实现C/C++的调试工作的;
CIL指令:
1. (gdb) help(h) #查看help
2. (gdb) run(r) #重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件)
3. (gdb)start # 单步执行,运行程序,停在第一行执行语句
4. (gdb)list(l) # 查看源代码(list-n,从第n行开始查看代码。list+函数名字:查看具体函数)
5. (gdb)set # 设置变量的值
6. (gdb)next(n) # 单步调试(逐语句:跳入自定义函数内部执行)
7. (gdb)step(s) # 单步调试(逐语句:跳入自定义函数内部执行)
8. (gdb)print(p) # 打印数值以及地址
9. (gdb)quit(q) # 退出gdb
10. (gdb)break+num(b) # 在第num行设置断点
11. (gdb) info breakpoints(ib) # 查看当前设置的所有断点
12. (gdb) enable breakpoints # 启用断点
13. (gdb) disable breakpoints # 禁用断点
Tips:
1. 编译程序时需要加上-g,之后才能用gdb进行调试:
gcc -g main.cpp -o main
2. 回车键可以重复上一个命令
3. continue(c) 执行到下一个断点的位置
> 5. `Cmake`
1. 基本语法格式:指令(参数1,参数2~~~)
参数用括弧括起来,参数之间使用空格或者分号隔开
2. 指令是大小写无关的,参数和变量是大小写相关的
3. 变量使用doller方式取值,但是IF控制语句中是直接使用变量名
4. set-显式的定义变量
set(VAR [VALUE][CACHE TYPE DOCSTRING [FORCE]])
set(SRC sayhello.cpp hello.cpp)
5. include_directories-向工程添加多个特定的头文件搜索路径
---->相当于指定g++编译器的-I参数
6. link_directories-向工程添加多个特定的库文件搜索路径
----->相当于制定g++编译器的-L参数
7. add_library-生成库文件
add_library(libname [SHARED][STATIC][MODULE][EXCLUDE_FROM_ALL] source1 source2)
add_library(hello SHARED ${SRC})
8. `add_compile_options添加编译参数`
add_compile_options(<options>)
add_compile_options(-wall -std=c++11 -o2)
9. add_excutable生成可执行文件
add_excutable(exname source1 source2)
10. tagrget_link_libraries为target添加需要链接的共享库
---->相同于g++编译器的-I参数
target_link_libraries(target library1<debug | optimized library2...>)
target_link_libraries(
main hello
)
11. add_subdirectory向当前工程添加存放源文件的子目录,并可以制定中间二进制和目标二进制存放的位置
12 aux_source_directory发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建元文件列表
aux_source_directory(dir VARIABLE)
定义SRC变量,他的值为当前目录下的所有源代码文件
aux_source_directory(. SRC)
编译SRC变量所代表的源代码文件,生成main可执行文件
add_excutable(main dollar{SRC})
> 6. Cmake常用变量
CMAKE_C_FLAGES gcc编译选项
CMAKE——CXX——FLAGES g++编译选项
CMAKE_BUILD_TYPE 编译类型(Debug Release)
add_definitions("-Wall -g") 和set (CMAKE_BUILD_TYPE Debug)作用相同
> 7. CMake编译规则
第一种: 包含源文件的子文件夹包含CMakeList.txt文件,主目录的CMakeList.txt通过add_subdirectory添加子目录即可
第二种:包含源文件的子文件夹未包含CMakeList.txt文件,子目录的编译规则要体现在主目录的CMakeList.txt中
构建方式采用外部构建:
步骤一:创建build mkdir build
步骤二:进入build文件夹 cd build
步骤三:编译上级目录的CMakeList.txt 生成Makefile和其他文件 cmake ..
步骤四:执行make命令,生成target make
> 8. `Vim` 编译器
现在只会简单的插入,覆盖和退出,后续专门学习一下;
插入:i
覆盖: esc+shift+:+w
退出::q
设置tab为四个空格位置: :set ts=4
显示行号: :set nu

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/26704.html