参考自MeouSker77/Cpp17

结构化绑定

结构化绑定允许你用一个对象的元素或成员同时实例化多个实体。

概念

1
2
3
4
5
6
7
struct Test
{
int i;
std::string str;
}
Test test;
auto [intVal, strVal] = test;
阅读全文 »

引入

由于软件需求,需要在QTableWidget中使用自定义控件显示数据,使用CellWidget在数据过多时会明显卡顿,遂找寻另外办法解决。

解决

使用自定义代理重写paint函数以进行优化。

此处以QLabel为例子:

阅读全文 »

引入

在某次使用QListView进行数据展示时,要求每次添加数据后选中最后一项,发现在插入数据过多后,会出现选中最后一项但滚动条固定到某个位置的情况。

最后发现是setLayoutMode方法中设置了batched属性,导致数据项更新后数据按批次排列,导致后续批次的项目无法与界面进行交互。

总结

layoutMode属性中:

阅读全文 »

引入

在某次调试程序时,发生程序崩溃,最终定位到是qDeleteAll发生内存访问越界。

发现是先前delete后未对容器进行clear操作,导致程序崩溃。

总结

qDeleteAll只负责释放容器元素内存,但没有对容器的置空操作。若无意间二次再执行qDeleteAll过程,程序必会崩溃。

阅读全文 »

引入

看下面这段代码:

1
2
3
4
5
6
7
8
9
try
{
File *file = fopen("123.txt","rw+");
// do something...
}
catch(const Exception &e)
{
// do something for exception...
}

当在do something过程中,发生异常,则会出现file未关闭而导致内存泄漏的情况。在Java中,有一个finally函数可以在此情况后调用。而在C++中,如何去避免这种情况呢?

解决

阅读全文 »

引入

通常,我们需要异步执行一个函数时,通常使用std::thread创建一个线程,但当我们想要获取这个子线程返回的结果时,可能就需要使用引用或全局变量的方式。

这里引出std::asyncstd::async是一个函数模板,此会启动一个异步任务,执行任务,并最终将结果返回至std::future当中。

std::async相比std::thread有更好的控制性,可以进行延迟创建。

详细

阅读全文 »

引入

看看如下函数定义:

1
2
3
DoSomething(char (&arr) [10]);     // 10个元素的数组, sizeof(arr)==10*sizeof(char)==10
DoSomething(char arr[]); // arr退化为指针, sizeof(arr)==sizeof(char*)
DoSomething(char *arr, size_t n); // 处理任意含n个char的连续内存

通常我们为了程序的复用性,会使用最后DoSomething(char *arr, size_t n);的形式,通过传入字符指针和长度灵活处理。但可能出现以下情况:

1
2
char str[10];
DoSomething(str, 20);
阅读全文 »

什么是KCP协议

首先看看官网的介绍:

1
2
KCP是一个快速可靠协议,能以比 TCP浪费10%-20%的带宽的代价,换取平均延迟降低 30%-40%,且最大延迟降低三倍的传输效果。纯算法实现,并不负责底层协议(如UDP)的收发,需要使用者自己定义下层数据的发送方式,以 callback的方式提供给 KCP。连时钟都需要外部传递进来,内部不会有任何一次系统调用。
TCP是为流量设计的(每秒内可以传输多少KB的数据),讲究的是充分利用带宽。而 KCP是为流速设计的(单个数据从一端发送到一端需要多少时间),以10%-20%带宽浪费的代价换取了比 TCP快30%-40%的传输速度。

简而言之,KCP不像TCP那样大公无私,它只会保证自己的传输速率,不管整个网络的拥塞情况。

TCP的特点是可靠传输(累积确认、超时重传、选择确认)、流量控制(滑动窗口)、拥塞控制(慢开始、拥塞避免、快重传、快恢复)。KCP对这些参数都可配,且不需要建立/关闭连接的过程。

阅读全文 »