1. c_str()函数 返回值类型是 const char *.
c_str是string类的一个函数,可以把string类型变量转换成 char* 变量
文件操作中open()要求的是一个char*字符串 ,当文件名是string时需要转换,当文件名是字符数组型时就不需要此转换。
//c_str()的简单使用 // char *c定义会报错 无法将const char* 转换为char* const char *c; string s = "abcde"; c = s.c_str(); cout<2 stringstream 文件流的输入和输出操作,可以将类型进行转换
例,string类型的变量变为int类型
stringstream sstream; string strResult; int nValue = 1000; // 将int类型的值放入输入流中 sstream << nValue; // 从sstream中抽取前面插入的int类型的值,赋给string类型 sstream >> strResult; cout<<"string strResult: "<3.cv::FileStorage 对xml、yaml等文件进行读写
//构造函数 filename 文件名称 flags 文件的打开模式,READ 只读 WRITE只写 FileStorage::FileStorage(const String& filename,int flags,const String& encoding= String()); //几个重要的函数 FileStorage::release() : 关闭文件 FileStorage::isOpened() :判断文件是否打开 //使用 cv::FileStorage fsSettings(filename, cv::FileStorage::READ); //只读对txt文件读写时
ifstream fTimes; string strPathTimeFile //c_str是string类的一个函数,可以把string类型变量转换成char*变量 //open()要求的是一个char*字符串 //当文件名是string时需要转换,当文件名是字符数组型时就不需要此转换 fTimes.open(strPathTimeFile.c_str());参考问篇文章,讲的很详细。
(1条消息) 【ORB_SLAM2源码解读】从文件或终端读写yaml和txt文件_小秋SLAM项目实战教程的博客-CSDN博客_slam使用教程https://blog.csdn.net/qq_21950671/article/details/108703089?spm=1001.2014.3001.5501
4.copyMakeBorder 对边界扩展的区域进行像素填充
将源图像拷贝到目的图像的中央,四面填充指定的像素;如果已经拷贝到中间,只填充边界
void copyMakeBorder(InputArray src, OutputArray dst, int top, int bottom, int left, int right, int borderType, const Scalar& value=Scalar() )src:源图像
dst:目标图像
top bottom left right:需要扩展的大小
border:扩展方式,取值如下:
enum BorderTypes {
BORDER_CONSTANT = 0, //!< `iiiiii|abcdefgh|iiiiiii` with some specified `i`
BORDER_REPLICATE = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
BORDER_REFLECT = 2, //!< `fedcba|abcdefgh|hgfedcb`
BORDER_WRAP = 3, //!< `cdefgh|abcdefgh|abcdefg`
BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
BORDER_TRANSPARENT = 5, //!< `uvwxyz|abcdefgh|ijklmno`BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_ISOLATED = 16 //!< do not look outside of ROI
};参考:opencv之边界扩展copyMakeBorder_Captain_zp的博客-CSDN博客_opencv边界扩展https://blog.csdn.net/zhangping1987/article/details/51141658
5. resize ORB-SLAM2中使用resize函数实现图像缩放
resize(image, //输入图像 mvImagePyramid[level], //输出图像 sz, //输出图像的尺寸 0, //水平方向上的缩放系数,留0表示自动计算 0, //垂直方向上的缩放系数,留0表示自动计算 cv::INTER_LINEAR); //图像缩放的差值算法类型,这里的是线性插值算法6.release
OpenCV参考手册之Mat类详解(三)_一码超神的博客-CSDN博客_mat 指定大小https://blog.csdn.net/giantchen547792075/article/details/9107877
7.std::back_inserter 末尾添加元素
拷贝v2到v1的末尾 std::copy(v2.begin(), v2.end(), std::back_inserter(v1));C++ STL back_inserter 函数说明 - 简书 (jianshu.com)https://www.jianshu.com/p/6862a79eba0a
8.class
privite protected public区别:
①访问范围
private: 只能由该类中的函数、其友元函数访问;派生类不能访问,该类的对象也不能访问.
protected: 可以被该类中的函数、其友元函数访问以及 派生类的函数访;但不能被该类的对象访问
public: 可以被该类中的函数、派生类的函数、其友元函数访问,也可以由该类的对象访问②类继承后方法属性变化:
private继承,父类的所有方法在派生类中变为private;
protected继承,父类的protected和public方法在派生类中变为protected,privete不变;
public继承,父类中的方法属性不发生改变。③三种访问权限
private:只允许本类的成员函数访问,如果类外要查看私有成员的值可以通过public类型的成员函数查看(setXXX 设置私有成员变量的值,getXXX获取私有成员变量的值)。
protected:允许本类和派生类的成员函数访问
public:可以被任意访问
9. new关键字
new在生成对象时完成了三件事:①为对象开辟内存空间(堆区) ②调用类的构造函数 ③将生成的对象的地址返回。new分配内存后需要使用delete清理,否则会造成内存泄漏。
使用new在堆区创建的对象是匿名的,不能直接使用,必须用一个指针指向它,在借助指针来访问它的成员变量或成员函数。 Student *pStu = new Student;
后续通过-> 访问成员变量或成员函数。
10.explicit 不允许发生隐式转换
class Point { public: int x, y; Point(int x = 0, int y = 0) : x(x), y(y) {} }; void displayPoint(const Point& p) { cout << "(" << p.x << "," << p.y << ")" << endl; } int main() { Point p(1); displayPoint(p); }displayPoint只传了一个参数,在调用Point的构造函数时,第二个参数使用了默认参数,这里触发了函数的隐式调用,如果没用这个默认参数报错。
为了避免这种情况出现使用explicit显示调用,
explicit Point(int _x = 0, int _y = 0 ) : x(_x), y(_y) {}11.虚函数:实现了多态的机制。多态是使用父类型指针指向子类的实例,然后通过父类的指针调用实际子类的成员函数。
12.成员变量、局部变量、全局变量、静态成员变量的区别
成员变量:在堆区创建内存; 在类中定义 ; 随着对象的创建而存在
局部变量:在栈区创建内存; 在方法中定义 ; 随着方法的调用而存在
全局变量:所有的方法都可以访问。
静态成员变量:static 修饰的成员变量。static 成员变量属于类,不属于某个具体的对象,即使创建多个对象,也只为 static 成员变量 分配一份内存,所有对象使用的都是这份内存中的数据。初始化:必须在类的外部初始化,如 int Person::p_total = 0, 只有在初始化的时候为它分配内存。
注意:static 成员变量不占用对象的内存,而是在所有对象之外开辟内存,意味着static 成员变量不随对象的创建而分配内存,也不会随对象的销毁而释放内存。
静态成员函数的主要目的是访问静态成员变量。静态成员函数在声明时要加 static,在定义时不能加 static。
(什么时候使用静态变量呢?)现在有两个类对象A和B,当修改A的成员函数时,不会影响B的成员函数,但有时候需要这些数据相互影响,如A改变了某一个变量,希望B能检测到。一般在求具体的总数时用到静态成员变量,具体看下面链接的代码。
C++ static静态成员函数详解 (biancheng.net)http://c.biancheng.net/view/2228.html13.c++中内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
栈:编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。程序的局部变量和函数参数存储在栈区。
堆:使用new分配的内存就在堆区,需要delete手动释放内存,堆的空间小于等于实际的物理内存,分配速度慢。
自由存储区:由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。[注] 堆和自由存储区一般认为是同一名词。 或者,自由存储区的一部分被开成堆,剩下的则是未使用。堆和栈都可以在自由存储区里进行自动扩展,直到2者相接而成为内存耗尽。
全局/静态存储区:全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。程序结束自动释放。
常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改,而且方法很多)[注] 常量存储区则是“全局/静态存储区”的一部分,在os支持常量段的情况下,编译器可以把一部分const的全局变量放在这个位置。而且,这个“全局/静态存储区”并没有被C、C++标准给出名称,都是俗称,各个资料上可以名字差异很大。
关于堆栈的区别:
1、管理方式不同;
2、空间大小不同;
3、能否产生碎片不同;(碎片应该是操作系统中的概念)
4、生长方向不同;
5、分配方式不同;
6、分配效率不同;
14. 引用 &
int &a = b 等价于 int * const a = b
引用是一个指针常量,即一个常量,类型是指针。当编译器遇到引用变量 a 的时候会执行 * 操作。
常引用:const int &a = b 等价于 const int * const a = b , 此时a的地址不可以修改,指向的内存空间也不能修改。
int b = 10; const int &a = b; cout<<"a = "<void ComputeImageBounds(const cv::Mat &imLeft);为什么使用引用?形参的变化不会影响实参。上面代码中如果没用引用,函数只是对形参imLeft进行修改,实际的参数并没有变化,加入引用表示传入其实是实际参数。
为什么引用前加const?追求效率,又希望避免改变原来的imLeft。
15. 线程和进程
对于操作系统来说,一个任务就是一个进程,一个进程内多个子任务就是线程。
进程是操作系统分配资源的单元;而线程是进程的一个实体,是CPU调度和分配的基本单位。
线程没有独立的内存单元,不能够独立执行,必须依存在应用程序中。
引入线程的好处:线程快!创建、终止、切换都很快!总结:
一个程序至少有一个进程,一个进程至少有一个线程。
进程在执行过程中拥有独立的内存单元,而多个线程共享内存。
虽然线程拥有单独的程序运行入口,出口,但不能独立执行。进程间通信也就是所谓的IPC(Interprocess communication)问题,主要是指进程间交换数据的方式。
进程是相互独立的,并不需要条件变量、互斥锁这些机制,要锁也是文件锁这种大锁。而线程需要互斥锁的原因是:线程之间的资源室共享的,需要程序员来完成变量级别的同步。【C++】 命名空间 类 函数 变量 进程 线程_小秋SLAM项目实战教程的博客-CSDN博客_c命名空间的定义和使用https://blog.csdn.net/qq_21950671/article/details/103528012?spm=1001.2014.3001.5501



