目录
- 1.#ifndef/#define/#endif
- 2.C++中map类型的使用
* - 2.1 删除元素
- 2.2 map的用法
- 2.3 判断map中key值是否存在
- 3.虚函数后面的const=0
- 4.SDK开发的注意点
- 5.虚函数指针和虚函数表——对象内存布局
- 6.如何编写抽象类接口
- 7.new A与new A()的区别
- 8.C++ 实例化对象并访问数据成员和成员函数的两种方式
* - 8.1 在栈中实例化对象
- 8.2 在堆中实例化对象
- 9.实际开发Qt中实例化对象的步骤
- 10.回调函数
- 11.在VS编译器中报错:C4700 使用了未初始化的局部变量
- 12.c++的形参前面加上&与const的意义
- 13.关于创建数组使用malloc方法及需要注意free() 和memset() 的坑和必要性
1.#ifndef/#define/#endif
在Qt中新建一个类C++ Class时(.cpp和.h文件),.h文件中会默认出现如下代码段:
#ifndef WIDGET_H
#define WIDGET_H
#endif
目的是为了代码在编译的时候防止被多次包含,增加编译的时间等等。
#ifndef WIDGET_H
意思是 “if not define WIDGET_H”,如果不存在widget.h,
接着的语句应该 #define WIDGET_H
,就引入widget.h,
最后一句应该写 #endif
,否则不需要引入。
2.C++中map类型的使用
#include
变量的声明
map<string, string> mapStudent
2.1 删除元素
cmap.erase("bfff");
map<string,int>::iterator key = cmap.find("mykey");
if(key!=cmap.end())
{
cmap.erase(key);
}
cmap.erase(cmap.begin(),cmap.end());
2.2 map的用法
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
insert() 插入元素
max_size() 返回可以容纳的最大元素个数
size() 返回map中元素的个数
swap() 交换两个map
get_allocator() 返回map的配置器
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
2.3 判断map中key值是否存在
std::cout << "***********测试map的使用************" << std::endl;
std::map<std::string, std::tuple<int, std::string>> map_test;
std::get<0>(map_test["1"]) = 11;
std::get<1>(map_test["1"]) = "111";
if(map_test.find("111") == map_test.end()) {
std::cout << "不存在" << std::endl;
}
else {
std::cout << "存在" << std::endl;
}
std::cout << "***********************************" << std::endl;
3.虚函数后面的const=0
https://blog.csdn.net/weixin_45525272/article/details/105840562
const 和 = 0 没有关系,需要分开理解:
- (1)= 0 说明这个成员函数是纯虚函数,也就是它可以没有定义,只有接口,由它的继承类具体定义它的行为,当然也可以定义为缺省的函数体。
缺省的函数体:https://blog.csdn.net/qq_40335930/article/details/100161663 - (2)成员函数后面使用 const 修饰,const表明不能修改其数据成员,即在这个函数内不能修改类的成员变量,除非那个成员变量是mutable。
关于 mutable的用法和意义:https://blog.csdn.net/luke_sanjayzzzhong/article/details/104362340
; 4.SDK开发的注意点
5.虚函数指针和虚函数表——对象内存布局
; 6.如何编写抽象类接口
场景需求:假设当前使用海康相机SDK进行二次开发,编写sdk_camera.h和sdk_camera.cpp,可能会使用很多细节函数功能的API接口,我们不希望对用户开放很多的接口(比如相机保存当前帧采集到的图像可能需要经过”开始采集”——”保存当前帧图像信息”——”将当前帧图像存储为文件”——”释放当前帧缓存”等几个步骤,可以直接给用户一个API(保存图像))。
这时候就需要编写相机类抽象接口,设一个 camera.h作为基类,里面都定义纯虚函数即 virtual A() = 0;
,纯虚函数只需要对函数进行声明,不需要进行定义,即不需要编写 camera.cpp文件,但其派生类必须对其基类中声明的函数进行函数重写,即达到多态的效果。
举例:
camera.h
#ifndef CAMERA_H
#define CAMERA_H
#include
#include
class Camera
{
public:
virtual ~Camera() = default;
virtual std::vector<std::string> getConnectedCameraNames() = 0;
};
#endif
hik_camera.h
#ifndef HIK_CAMERA_H
#define HIK_CAMERA_H
class HikCamera : public Camera
{
public:
HikCamera();
~HikCamera();
std::vector<std::string> getConnectedCameraNames() override;
#endif
hik_camera.cpp
#include "hik_camera.h"
HikCamera::HikCamera()
{
}
HikCamera::~HikCamera()
{
}
std::vector<std::string> HikCamera::getConnectedCameraNames()
{
××××××××××××;
××××××××××××;
××××××××××××;
××××××××××××;
××××××××××××;
}
7.new A与new A()的区别
总结:都会执行默认构造函数,带()会进行值的初始化。
举例:
#include
class Test
{
public:
int data = 6;
};
int main(void) {
Test* x = new Test();
Test* y = new Test;
std::cout << x->data << std::endl;
std::cout << y->data << std::endl << std::endl;
int* x1 = new int();
int* y1 = new int;
std::cout << *x1 << std::endl;
std::cout << *y1 << std::endl;
return 0;
}
输出:
8.C++ 实例化对象并访问数据成员和成员函数的两种方式
8.1 在栈中实例化对象
从栈中实例化对象(花括号中):通过 点访问对象,用完,离开花括号,系统就会把分配的内存自动回收。
举例:
#include
class TV
{
public:
char name[20];
int type;
void vol();
void power();
};
int main()
{
TV tv;
tv.type = 5;
std::cout << tv.type << std::endl;
return 0;
}
输出:
8.2 在堆中实例化对象
在堆中实例化对象:(new分配的内存空间),通过 箭头->访问对象,在堆中申请的内存用完需要程序员释放。
举例:
#include
class TV
{
public:
char name[20];
int type;
void vol();
void power();
};
int main()
{
TV* p = new TV();
p->type = 4;
std::cout << "type=" << p->type << std::endl;
delete p;
p = NULL;
return 0;
}
输出:
9.实际开发Qt中实例化对象的步骤
在.h文件中实例化对象指针,在.cpp文件中实例化对象。
以使用 6 中的相机接口为例。
.h
HikCamera *camera[MAX];
或者
HikCamera *camera = NULL;
.cpp
camera[i] = new HikCamera;
或者
camera = new HikCamera;
10.回调函数
https://www.bilibili.com/video/BV1X44y1N7J4?spm_id_from=333.337.search-card.all.click
https://blog.csdn.net/sinat_31608641/article/details/108409828
11.在VS编译器中报错:C4700 使用了未初始化的局部变量
在编程时,如果声明变量未初始化的话,编译器会自动给变量赋一个初始值,比如int默认初始值是0,char默认初始值是’\0’。
对于指针类型来说, 未初始化时不可对内容进行赋值操作。
char *p;
cin.getline(p,10);
*p = new char;
cin.getline(p,10);
12.c++的形参前面加上&与const的意义
- *形参前面加上&
1.& 表示取地址符,即变量的地址。
2.在声明或定义函数时,如有字符串等类型的参数,可以使用取地址符,如&device_name表示的就是device_name这个变量的地址,这样在调用函数时,避免多次值拷贝,采用值引用,如
void getMachineName(std::string &device_name);
3.传递引用,可以在函数内部更改传入变量的值;传地址,使得函数内对该变量的修改全局有效。
- *形参前面加上const
在哪个函数的形参前面加上了const,则在那个函数里面,被const修饰的形参就不能被更改。
13.关于创建数组使用malloc方法及需要注意free() 和memset() 的坑和必要性
- 1:一定要初始化,因为在Debug模式下默认初始化是0,但到了release模式下默认初始化是随机数,会出现在Debug模式下没问题,但到release模式下计算出来的就不对了,养成变量初始化的好习惯。
- 2:数据用完后一定要用free()手动释放掉,(系统不会自动释放掉),否则在下次循环操作下内存(堆)就不够用了,导致程序花了很大的时间寻找连续物理内存,最终还是找不到合适的,程序就停了很长时间再崩溃。
Original: https://blog.csdn.net/qq_45445740/article/details/126918699
Author: boss-dog
Title: C++开发过程中的笔记
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/542235/
转载文章受原作者版权保护。转载请注明原作者出处!