引入

C++语言不支持栈Stack (此处出现的堆栈为操作系统的堆栈) 上的可变长度数组:

1
2
3
4
5
int fun1(unsigned n)
{
int arr[n + 1]; // 错误!
...
}

还有一种办法则是在堆Heap上构建:

1
2
3
4
5
6
int fun2(unsigned n)
{
int *arr = new int[n + 1]; // 可行
...
delete arr;
}
阅读全文 »

引入

在查看关于processEvent时对于其第二个参数产生疑惑,Qt是如何保持高精度的计时的呢?

而在需要一个计时器时,通常会想到QTimer,通常对其的使用方式有两种:

  • 重复可用的计时器:创建一个QTimer对象,每过一段时间进行一个操作,即将一个QTimer对象和信号连接到槽函数
  • 单次触发的计时器:使用静态函数QTimer::singleShot,触发某些需要延迟触发的操作或需要在当前当不是现在(即想要执行,但可能立即执行会产生问题,使用interval0singleShot可以实现将其加入函数执行队列中);

废话结束,看源码吧

阅读全文 »

借鉴自CSDN

概述

在多线程同步时,条件变量是一个很好的选择,在使用时也需要注意。

一个线程调用QWaitCondition::wait进行等待,另一个线程调用QWatiCondition::wakeAllQWaitCondition::wakeOne进行唤醒。

示例

阅读全文 »

概述

众所周知,Qt实现多线程的方式有两种,一种是通过子类化QObject并将该类实例化后调用QObject::moveToThread,将对象的所有函数执行放到另一个线程当中;另一种则是通过子类化QThread后重写run内的内容。当然,QtConcurrent::run不算在此内。

第一种方法中,我们可以很容易得到槽函数会在moveToThread的那个线程中执行。再这,我们着重讨论第二种办法。

QThread

通常,我们对QThread子类化后,会将需要执行的内容放在run函数中。Qt也告诉我们:**QThread实例位于实例化它的旧线程中,而不是位于调用run()的新线程中。这意味着QThread的所有队列槽函数和调用的方法都将在旧线程中执行。因此,希望在新线程中调用槽的开发人员必须使用worker对象方法;新的槽函数不应该直接实现到子类QThread中。**

阅读全文 »

概述

在使用QStringQByteArray等容器时,都会碰到一个名词隐式数据共享。说起来比较高大上,通俗一点就是写时复制(copy-on-write),当两个对象共享同一份数据时通过浅拷贝实现数据块的共享,如果数据不改变,不进行数据的复制。而当某个对象需要改变数据时则执行深拷贝。

例子

此处验证QString的隐式数据共享:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
QString s1 = "abcdefg";
QString s2 = s1;

// output will be the same
qDebug() << s1.constData();
qDebug() << s2.constData();

// this step makes a deep copy
s2[0] = 'A';

// output will be different
qDebug() << s1.constData();
qDebug() << s2.constData();
阅读全文 »

概述

在使用多线程时,我们经常会子类化QThread或将QObject``moveToThread来实现。

Qt中提供了一种高级方法,即QtConcurrentQtConcurrent模块提供了包括runmapfilter函数。

Concurrent Run

函数原型:

阅读全文 »

概述

通常我们会在类或结构体定义中见到定义变量时在后面加冒号和数字,如int var : 4

这是位域定义的标准形式。

位域定义的意义

有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。

阅读全文 »

概述

传统C语言使用预处理器常量来决定数值的极值,其中整数常量定义于或<limits.h>中,浮点常量定义于或<float.h>中。

在C++中使用一个numeric_limit模板类提供这些常值;
numeric_limit的优势:

  • 提供更好的类型安全特性;
  • 借此tamplate以核定一些极值;

常用变量函数

阅读全文 »

概述

工作需要,需要对浮点数据进行验证修复,遂想到使用QDoubleSpinBox,但自带的函数不足以满足我的需求,故自行子类化一个SpinBox

需求

  • 设定默认值和范围,范围基于默认值;
  • 设定梯度,如果超出范围或输入数据与默认数据的差不是梯度的整数倍则修正输入数据。

构思

阅读全文 »