C++开发过程中的笔记

1.#ifndef/#define/#endif

  在Qt中新建一个类C++ Class时(.cpp和.h文件),.h文件中会默认出现如下代码段:

#ifndef WIDGET_H
#define WIDGET_H

#endif // WIDGET_H

  目的是为了代码在编译的时候防止被多次包含,增加编译的时间等等。

  #ifndef WIDGET_H意思是 “if not define WIDGET_H”,如果不存在widget.h,
  接着的语句应该#define WIDGET_H,就引入widget.h,
  最后一句应该写#endif,否则不需要引入。

2.C++中map类型的使用

#include <map>

变量的声明

map<string, string> mapStudent

2.1 删除元素

// 删除键为bfff指向的元素
cmap.erase("bfff");
 
// 删除迭代器 key所指向的元素
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 没有关系,需要分开理解:

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 <string>
#include <vector>

class Camera
{
public:
    virtual ~Camera() = default;

    // 获取所有可连接的相机
    virtual std::vector<std::string> getConnectedCameraNames() = 0;
};

#endif // CAMERA_H

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_H

hik_camera.cpp

#include "hik_camera.h"

HikCamera::HikCamera()
{
}

HikCamera::~HikCamera()
{
}

std::vector<std::string> HikCamera::getConnectedCameraNames()
{
    ××××××××××××;
    ××××××××××××;
    ××××××××××××;
    ××××××××××××;
    ××××××××××××;
}

7.new A与new A()的区别

  总结:都会执行默认构造函数,带()会进行值的初始化。

举例:

#include <iostream>

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 <iostream>

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 <iostream>

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()手动释放掉,(系统不会自动释放掉),否则在下次循环操作下内存(堆)就不够用了,导致程序花了很大的时间寻找连续物理内存,最终还是找不到合适的,程序就停了很长时间再崩溃。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Dev C是一款免费的集成开发环境(IDE),可用于C/C++语言的编程。以下是一些关于Dev C的教程笔记。 首先,要使用Dev C进行编程,我们需要先安装该软件。可以在官方网站下载其安装程序,然后按照提示进行安装。 安装完成后,我们可以打开Dev C开始编程。在新建项目时,可以选择C或C++语言,并给项目命名。在项目,我们可以添加源文件、头文件等,并编写相应的代码。 Dev C具有很多实用的功能,其之一是自动补全。当我们开始输入代码时,Dev C会自动提示可能的命令或关键字,节省了编写代码时的时间和劳力。 在编写代码过程,我们可以使用Dev C的内置调试器来调试程序。当程序出现错误时,可以设置断点,并逐步执行代码,以便找到错误所在。 另外,Dev C还具有集成的编译器,可以将我们编写的程序转换为机器语言。编译器会检查代码的错误并生成可执行文件,供我们运行和测试。 除此之外,Dev C还提供了丰富的库函数和命令,方便我们进行各种操作,如文件读写、内存管理等。 最后,值得一提的是,由于Dev C是一个开源软件,其源代码可供修改和定制。这意味着我们可以根据自己的需求对其进行扩展和改进,进一步提高编程效率和体验。 总之,使用Dev C进行C/C++编程是一种方便和高效的选择。通过学习其基本功能和使用方法,我们可以更好地掌握编程技能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

boss-dog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值