文章目的
记录一下通过c++编写slam程序过程当中学习到的东西,比如c++中所用到的库都是什么意思,为什么要引用这些库等。
接下来,将会以slam14讲的章节为索引,记录里面遇到的c++方面的知识,也会从最基础的开始。
CH2
CH2-C++
using namespace std
using namespace std:该语句的用法是指,调用std命名空间下的函数。为了解决命名冲突的问题,即自己定义的某些变量或函数的名称,与调用库中函数变量或名称相同而产生冲突。
用了这句using namespace std;
就相当于直接把它的命名空间的壳拆了,也就是可以直接访问里边的所有函数和对象,如cout、cin、endl……
【命名空间】using namespace std是什么意思?_罅隙`的博客-CSDN博客
iostream
iostream: 一个包含C++输入输出的库,该库的源码中定义了std命名空间。因此,在调用该库的时候,如果不使用上面的语句using namespace std对命名空间展开,或者不使用std::表示调用std命名空间下的函数或者变量,则没有办法在程序中正常使用cout或者cin,因为cin和cout都在std命名空间下。
头文件宏定义
为了防止头文件被重复调用例如:
//student.h
class Student {
//......
};
//school.h
#include "student.h"
class School {
//......
private:
Student stu[50];
};
//main.cpp
#include "student.h"
#include "school.h"
int main() {
//......
return 0;
}
这里在main中调用student.h和school.h,但是在school.h中已经对student.h进行了调用,此时编译会报错,即对头文件重复调用的错误。这里我们只需要通过宏定义,对头文件的重定义错误进行纠正。
#ifndef _NAME_H
#define _NAME_H
//头文件内容
#endif
其中,_NAME_H 是宏的名称。需要注意的是,这里设置的宏名必须是独一无二的,不要和项目中其他宏的名称相同。
当程序中第一次 #include 该文件时,由于 _NAME_H 尚未定义,所以会定义 _NAME_H 并执行“头文件内容”部分的代码;当发生多次 #include 时,因为前面已经定义了 _NAME_H,所以不会再重复执行“头文件内容”部分的代码。
C++防止头文件被重复引入的3种方法(详解版)_c++防止头文件重复包含_致守的博客-CSDN博客
对于自定义的头文件,一定要注意调用时使用双引号,而不是尖括号。一些默认的头文件使用尖括号。
CH2-Cmake
CMAKE_BUILD_TYPE中debug和release的区别
对于一般项目没有太大区别,并且在slam过程中牵扯需要修改地层cmake的地方比较少,因此可以直接使用默认release版本。
库文件调用及使用
c++文件中,如果没有main函数,意味着该文件无法通过编译生成一个可执行文件。而在大多数时候,我们通过代码调用,把一些东西进行打包,供其他程序或者main函数进行调用,打包好的东西就叫做库。通过如下语句告诉cmake,libhelloslam.cpp将会变成一个叫做hello的库:
add_library(hello libhelloslam.cpp)
调用cmake编译完成后,就会在build中生成libhello.a文件,即静态库文件。使用如下语句可以生成共享库,共享库在调用时只有一个副本,更节省空间:
add_library(hello_shared SHARED libhelloslam.cpp)
lib.cpp文件用于定义函数,lib.h文件调用lib.cpp文件中对函数的定义,并被含有main函数的cpp文件所引用。生成共享库之后,通过如下语句将执行项目与生成的共享库链接:
target_link_libraries( usehello hello_shared)
这里需要注意,如果我们所调用的头文件不在当前目录下,需要对头文件的路径进行include,命令行如下:
#这里以系统自带的eigen3为例
include_directories("/usr/include/eigen3")
虽然cpp文件中可能会提示对应的头文件不存在,但是只要在cmakelist里面正确引用了路径即可。
CH3
CH3-C++
ctime库
ctime库包括了很多对于时间的运算,可以计算时间差。
c++中的ctime库_c++ ctime库_fang0jun的博客-CSDN博客
可以通过调用clock()函数,计算开始时间到结束时间CPU运行的时间单元数,再通过作差/单元数来计算时间。例程可以参考slam14讲。
cmath库
cmath库,顾名思义可以调用各种数学运算的库,类似于math.h。
C++ 13个cmath库函数!(史上最详细)-CSDN博客
\t、\n、\r
\n:表示换行操作,光标会移动到下一行(next line)
\t:表示水平制表空行操作,相当于Tab键,不会换行
\r:相当于回车,相当于光标回到本行首位置,不会换行;
Eigen报错
结果矩阵的维度错误:
不同数据类型矩阵相乘(例如float与double)
cout.precision()
C++的精度输出cout.precision()的使用_c++ precision_可即的博客-CSDN博客
四元数、旋转矩阵、旋转向量相互转化
【C++】Eigen 库中旋转向量、旋转矩阵、欧拉角、四元数的定义及互相转换_eigen 欧拉角转四元数_Amelie_xiao的博客-CSDN博客
CH3-Cmake
CMAKE_CXX_FLAGS
这里可能会用到很多的参数,但是-O3的意思是对代码进行优化。
include_directories
include_directories("/usr/include/eigen3")是指将该路径放到头文件搜索路径下。
如果头文件是自己写的,可以不用引。如果是第三方的头文件,需要使用 该命令引用以下。保险起见,最好所有都进行引用。
这里路径之所以直到eigen3,是因为cpp文件中的头文件是#include <Eigen/Dense>,结合上面的路径,总的路径就是/usr/include/eigen3/Eigen/Dense.h,否则就会提示路径找不到。
add_subdirectory
加入子工程项目,可以用来做一个整体的编译,将各个子工程项目通过对应的CMakeLists.txt文件一整个进行编译。
CH4
CH4-C++
.hpp文件和.h文件的区别
.hpp文件与.h文件的区别在于,.h文件中只会包含对函数的声明,没有实现,而.hpp文件中则会包含对函数的实现。在使用过程中,只需要对.hpp文件进行调用即可,无需再调用cpp库文件。
CH4-Cmake
find_package
find_package是给cmake提供寻找某个库头文件与库文件的指令,如果能够找到,就会提供头文件和库文件所在目录的变量。之后再通过targetlink或者include等命令包含库文件和头文件即可。
本质上是寻找第三方库所编译后的.cmake文件,找到后命名变量名称。
除了Eigen,别的库基本都是先find_package,再加上include_directories引头文件以及targenlink引库文件。或许有时需要通过set设置一下优先寻找路径。
# 设定优先找包路径
set(OpenCV_DIR /usr/local/share/OpenCV)
# 然后find_package找opencv时优先查找上面这个路径下的.cmake文件
# 如果符合版本要求就使用,不符合就会去默认找包路径再其他opencv版本
find_package(OpenCV 3.4.15 EXACT REQUIRED)
# EXACT表示版本必须一致,否则大版本一致即可
# REQUIED表示必须找到该包,否则停止,于此相反的是QUIET,找不到包也不会报错
find_package(OpenCV 3.4.15 EXACT REQUIRED)
CH5
CH5-C++
choron库
提供了time_clock、duration、time_point三个方面的相关函数
C++11计时器:chrono库介绍_森明帮大于黑虎帮的博客-CSDN博客
CV_8UC1含义
opencv学习日记——CV_8UC1 含义_英雄小摔哥的博客-CSDN博客
其中,CV_8UC3表示一共3个通道,每个通道都是8位,因此一共是24位的元素。
Opencv中立体视觉匹配算法
双目相机立体匹配算法BM和SGBM_cv::stereosgbm_没伞的行者的博客-CSDN博客
auto用法
auto可以自动推断变量的类型,是double还是float等等。
c++ auto类型用法总结_auto c++_慢下去、静下来的博客-CSDN博客
CH5-cmake
附录
catkin_make与cmake的区别
catkin_make实际上与下面的指令是等效的:
$ cd ~/catkin_ws
$ cd src
$ catkin_init_workspace
$ cd ..
$ mkdir build
$ cd build
$ cmake ../src -DCMAKE_INSTALL_PREFIX=../install -DCATKIN_DEVEL_PREFIX=../devel
$ make
就是对工作空间下的src里面的内容进行编译,所以cmakelist应该与src目录是平级的。
mkdir -p
mkdir -p catkin_ws/src是指,递归按照顺序,先创造catkin_ws,再创造src。如果只调用mkdir指令,则会报错catkin_ws不存在。因为mkdir指令只能一个一个文件夹进行创造。
VScode中引入第三方库
在vscode中引入第三方库如eigen,写代码调用时没有补全或者提示,需要进行如下操作:
【c++代码提示】VScode c++ 代码自动补全/智能提示设置_vscode c++提示_weixin_42461385的博客-CSDN博客
VScode乱报错
这个问题主要体现在,明明可以正常编译文件,但是vscode就是给你报错。最简单粗暴的方法就是删掉源码,重新下载一份即可。因为使用VScode的时候会自动生成.vscode文件,主要是这个文件乱作祟。