IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c++笔记(一) -> 正文阅读

[C++知识库]c++笔记(一)

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<<c<<endl;
//输出结果是abcde

s = "12345";
cout<<c<<endl;
//输出结果是12345

2 stringstream?文件流的输入和输出操作,可以将类型进行转换

例,string类型的变量变为int类型

stringstream sstream;
string strResult;
int nValue = 1000;
 
// 将int类型的值放入输入流中
sstream << nValue;
// 从sstream中抽取前面插入的int类型的值,赋给string类型
sstream >> strResult;
cout<<"string strResult:   "<<strResult<<endl;   //1000

3.cv::FileStorage? ?对xml、yaml等文件进行读写

//构造函数
//filename 文件名称
//flags 文件的打开模式,READ 只读 WRITE只写 
FileStorage::FileStorage(const String& filename,int flags,const String& encoding= String());

//几个重要的函数
FileStorage::isOpened() :判断文件是否打开
FileStorage::release() : 关闭文件

//使用
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());

总结:

对于整齐划一的格式,如ORBSLAM2中的字典、时间戳、图片序列这些选择用fstream?

多种多样的配置参数,如.yaml文件 选择用fileStorage

对于Mat的操作:

cv::Mat_<double> cameraMat = cv::Mat_<double>::zeros(3, 3);
cv::Mat_<double> distCoeffes = ( cv::Mat_<double>(5, 1)<< 0.1, 0.01, -0.001, 0.0, 0.0 );
// C++
std::cout<<"Camera Matrix"<<std::endl<<cv::Mat::Mat(cameraMat)<<std::endl;
std::cout<<"Distortion Coefficients"<<std::endl<<cv::Mat::Mat(distCoeffes)<<std::endl;
// cv::FileStorage
FileStorage fs;
fs << "Camera Matrix" << cameraMat;
fs << "Distortion Coefficients"<<distCoeffes;

?

?参考问篇文章,讲的很详细。

(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 = "<<a<<" b =  "<<b<<endl;
b = 11;//b是可以修改的,但是a不能修改
cout<<"a = "<<a<<" b =  "<<b<<endl;

a = 10 b = 10
a = 11 b = 11
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

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-19 11:50:18  更:2022-05-19 11:51:36 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:21:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码