一、描述
<QtGlobal> 头文件包括基本的全局声明。 它包含在大多数其他 Qt 头文件中。
二、类型成员
1、QFunctionPointer
这是 void (*)() 的 typedef,指向不带参数并返回 void 的函数指针。
2、QtMessageHandler
指向以下类型函数的指针的 typedef:
void myMessageHandler(QtMsgType, const QMessageLogContext &, const QString &);
3、enum QtMsgType
该枚举描述了可以发送到消息处理程序 (QtMessageHandler 指向的类型的函数) 的消息。可以使用枚举来识别各种消息类型并将其与适当的操作相关联。
- QtDebugMsg:由 qDebug() 函数生成的消息。
- QtInfoMsg:由 qInfo() 函数生成的消息。
- QtWarningMsg:由 qWarning() 函数生成的消息。
- QtCriticalMsg:由 qCritical() 函数生成的消息。
- QtFatalMsg:由 qFatal() 函数生成的消息。
- QtSystemMsg:QtCriticalMsg
4、整形
- uchar:无符号char
- qint8:有符号char。在 Qt 支持的所有平台上,此类型保证为 8 位。
- ushort:无符号short
- qint16:有符号short。在 Qt 支持的所有平台上,此类型保证为 16 位。
- uint:无符号int
- qint32:有符号int。在 Qt 支持的所有平台上,此类型保证为 32 位。
- ulong:无符号long
- qint64 / qlonglong:long long int 类型。
- quint64 / qulonglong:unsigned long long int 类型。在 Qt 支持的所有平台上,此类型保证为 64 位。
可以使用 Q_UINT64_C() 宏创建这种类型的变量:
quint64 value = Q_UINT64_C(932838457459459);
quintptr
用于在无符号整数中表示指针的整数类型。quint32 或 quint64 的类型定义。该类型保证与 Qt 支持的所有平台上的指针大小相同。
在具有 32 位指针的系统上,quintptr 是 quint32 的 typedef
在具有 64 位指针的系统上,quintptr 是 quint64 的 typedef
qintptr
用于在有符号整数中表示指针的整数类型。
qint32 或 qint64 的类型定义。该类型保证与 Qt 支持的所有平台上的指针大小相同。
在具有 32 位指针的系统上, qintptr 是 qint32 的 typedef
在具有 64 位指针的系统上, qintptr 是 qint64 的 typedef
qptrdiff
用于表示指针差异的整数类型。
qint32 或 qint64 的类型定义。 该类型保证与 Qt 支持的所有平台上的指针大小相同。
在具有 32 位指针的系统上,quintptr 是 quint32 的 typedef
在具有 64 位指针的系统上,quintptr 是 quint64 的 typedef
qreal
除非 Qt 配置了 -qreal float 选项,否则为 double 类型定义。
qsizetype
在 Qt 支持的所有平台上,该类型保证与 size_t 的大小相同。
三、函数成员
1、int qFpClassify(double val)
int qFpClassify(float val)
对浮点值进行分类。等同于标准库函数 fpclassify()。
返回值在 <cmath> 中定义:返回以下值之一,由 val 的浮点类决定:
- FP_NAN:不是数字
- FP_INFINITE:无穷大(正或负)
- FP_ZERO:零(正或负)
- FP_NORMAL:具有有限的完整尾数
- FP_SUBNORMAL:省略了尾数
const char *show_classification(double x)
{
switch(qFpClassify(x))
{
case FP_INFINITE: return "Inf";
case FP_NAN: return "NaN";
case FP_NORMAL: return "normal";
case FP_SUBNORMAL: return "subnormal";
case FP_ZERO: return "zero";
default: return "unknown";
}
}
int main(int argc, char *argv[])
{
double zero = 0;
qDebug()<<"1.0/0.0 : "<<show_classification(1/zero);
qDebug()<<"0.0/0.0 : "<<show_classification(0.0/zero);
qDebug()<<"DBL_MIN/2 : "<<show_classification(DBL_MIN/2);
qDebug()<<"-0.0 : "<<show_classification(-0.0);
qDebug()<<"1.0 : "<<show_classification(1.0);
}
2、QString qEnvironmentVariable(const char *varName)
QString qEnvironmentVariable(const char *varName, const QString &defaultValue)
将环境变量 varName 的值作为 QString 返回。 如果在环境中没有找到变量 varName 并且提供了 defaultValue,则返回 defaultValue。 否则返回 QString()。
int qEnvironmentVariableIntValue(const char *varName, bool *ok = nullptr)
返回环境变量 varName 的数值。 如果 ok 不为 null,则根据转换的成功将 *ok 设置为 true 或 false。相当于:
qgetenv(varName).toInt(ok, 0)
注意:值的长度是有限制的,对于 int 的所有有效值来说是足够的,不包括前导零或空格。 太长的值将被截断,或者此函数将 ok 设置为 false。
bool qEnvironmentVariableIsEmpty(const char *varName)
返回环境变量 varName 是否为空。相当于:
qgetenv(varName).isEmpty()
bool qEnvironmentVariableIsSet(const char *varName)
返回是否设置了环境变量 varName。相当于:
!qgetenv(varName).isNull()
QByteArray qgetenv(const char *varName)
以 QByteArray 形式返回名称为 varName 的环境变量的值。如果在环境中找不到该名称的变量,则此函数返回默认构造的 QByteArray。
要将数据转换为 QString,请使用 QString::fromLocal8Bit()。
在Windows 上,如果原始字符串包含在 ANSI 编码中无法表示的 Unicode 字符,则此函数可能会导致数据丢失。使用 qEnvironmentVariable() 代替。在 Unix 系统上,此功能是无损的。
bool qputenv(const char *varName, const QByteArray &value)
此函数设置名为 varName 的环境变量的值。如果变量不存在,它将创建变量。 如果无法设置变量,则返回false。
使用空值调用 qputenv 会删除 Windows 上的环境变量,在 Unix 上则设置为空。建议使用qunsetenv() 来实现完全可移植的行为。
bool qunsetenv(const char *varName)
此函数从环境中删除变量 varName。返回删除结果。
3、template <typename T> T qAbs(const T &t)
将 t 与类型 T 的 0 进行比较并返回绝对值。
4、template <typename T> typename std::add_const<T>::type &qAsConst(T &t)
将 t 强制转换为 const T。
此函数是 C++17 的 std::as_const() 的 Qt 实现,类似于 std::move() 的强制转换函数。但是std::move() 将左值转换为右值,此函数将非常量左值转换为常量左值。像 std::as_const() 一样,它不适用于右值,因为它不能在不留下悬空引用的情况下有效地实现右值。
它在 Qt 中的主要用途是防止隐式共享的 Qt 容器产生拷贝:
QString s = ...;
for (QChar ch : s) // 分离“s”(如果共享“s”,则执行深度复制)
process(ch);
for (QChar ch : qAsConst(s)) // 没有分离尝试
process(ch);
当然,在这种情况下,应该首先将 s 声明为 const:
const QString s = ...;
for (QChar ch : s) // 没有对 const 对象的分离尝试
process(ch);
重要的是要注意 qAsConst() 不复制它的参数,它只是执行一个 const_cast<const T&>(t)。 这也是它被设计为对右值失败的原因:返回的引用很快就会过时。 因此,虽然这有效(但分离了返回的对象):
for (QChar ch : funcReturningQString())
process(ch); // 返回的对象在循环的持续时间内保持活动状态
这不会:
for (QChar ch : qAsConst(funcReturningQString()))
process(ch); // 错误:ch 是从已删除的内存中复制的
5、template <typename T> const T &qBound(const T &min, const T &val, const T &max)
返回三个数的中间数。这相当于 qMax(min, qMin(val, max))。
int myValue = 10;
int minValue = 2;
int maxValue = 6;
int boundedValue = qBound(minValue, myValue, maxValue);
// boundedValue == 6
6、template <typename T> auto qConstOverload(T memberFunctionPointer)
返回指向常量成员函数的指针。
template <typename T> auto qNonConstOverload(T memberFunctionPointer)
返回指向非常量成员函数的指针。
struct Foo
{
void overloadedFunction(int, const QString &);
void overloadedFunction(int, const QString &) const;
};
int main(int argc, char *argv[])
{
auto constPtr = qConstOverload<int, const QString &>(&Foo::overloadedFunction);
auto ptr = qNonConstOverload<int, const QString &>(&Foo::overloadedFunction);
}
template <typename T> auto qOverload(T functionPointer)
返回指向重载函数的指针。模板参数是函数的参数类型列表。 functionPointer 是指向(成员)函数的指针。
qOverload() 需要启用 C++14。
struct Foo
{
void overloadedFunction();
void overloadedFunction(int, const QString &);
};
... qOverload<>(&Foo::overloadedFunction)
... qOverload<int, const QString &>(&Foo::overloadedFunction)
如果成员函数也是常量重载,则需要使用 qConstOverload 和 qNonConstOverload。
在 C++11-only 代码中,可以使用 QOverload、QConstOverload 和 QNonConstOverload:
... QOverload<>::of(&Foo::overloadedFunction)
... QOverload<int, const QString &>::of(&Foo::overloadedFunction)
7、template <typename T, typename U> T qExchange(T &obj, U &&newValue)
用 newValue 替换 obj 的值并返回 obj 的旧值。
这是 Qt 对 std::exchange() 的实现。 它与 std::exchange() 的不同之处仅在于它在 C++14 中已经是 constexpr,并且可用于所有支持的编译器。
下面是如何使用 qExchange() 来实现移动构造函数:
MyClass(MyClass &&other)
: m_pointer{qExchange(other.m_pointer, nullptr)},
m_int{qExchange(other.m_int, 0)},
m_vector{std::move(other.m_vector)},
...
对于类类型的成员,可以使用 std::move(),因为它们的移动构造函数会做正确的事情。但是对于原始指针或整数类型等标量类型,移动与复制相同。 因此,不能将 std::move() 用于此类类型,但可以使用 std::exchange()/qExchange() 来确保源对象的成员在进行下一个初始化时已经重置数据成员。
使用 qExchange() 迭代集合:
for (auto &e : qExchange(collection, {})
doSomethingWith(e);
这等同于:
{
auto tmp = std::move(collection);
collection.clear();//collection = {}
for (auto &e : tmp)
doSomethingWith(e);
}
8、quint32 qFloatDistance(float a, float b)
quint64 qFloatDistance(double a, double b)
9、QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, const QString &str)
生成格式化的字符串。该函数是线程安全的。
qFormatLogMessage 返回一个根据当前消息模式格式化的 QString。自定义消息处理程序可以使用它来格式化类似于 Qt 的默认消息处理程序的输出。
10、bool qFuzzyCompare(double p1, double p2)
bool qFuzzyCompare(float p1, float p2)
比较浮点值 p1 和 p2,如果它们相等则返回真,否则返回假。
比较 p1 或 p2 为 0.0 的值将不起作用,比较其中一个值为 NaN 或无穷大的值也不起作用。
如果其中一个值始终为 0.0,请改用 qFuzzyIsNull()。 如果其中一个值可能是 0.0,一种解决方案是将两个值都加上 1.0。
11、bool qFuzzyIsNull(double d)
如果 d 的绝对值在 0.0 的 0.000000000001 以内,则返回 true。
bool qFuzzyIsNull(float f)
如果 f 的绝对值在 0.0 的 0.00001f 内,则返回 true。
12、double qInf()
double qQNaN()
double qSNaN()
13、QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)
安装 Qt 消息处理程序。返回指向前一个消息处理程序的指针。
消息处理程序是一个打印调试消息、警告、严重和致命错误消息的函数。 Qt 库(调试模式)包含数百条警告消息,当发生内部错误(通常是无效的函数参数)时会打印这些消息。除非在编译期间设置了 QT_NO_WARNING_OUTPUT 或 QT_NO_DEBUG_OUTPUT,否则 Qt 内置发布模式也包含此类警告。如果实现自己的消息处理程序,则可以完全控制这些消息。
默认消息处理程序将消息打印到标准输出或 Windows 下的调试器。如果是致命消息,应用程序会立即中止。
只能定义一个消息处理程序,因为这通常是在应用程序范围内完成的,以控制调试输出。
要恢复消息处理程序,请调用 qInstallMessageHandler(0)。
#include <qapplication.h>
#include <stdio.h>
#include <stdlib.h>
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QByteArray localMsg = msg.toLocal8Bit();
const char *file = context.file ? context.file : "";
const char *function = context.function ? context.function : "";
switch (type) {
case QtDebugMsg:
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
break;
case QtInfoMsg:
fprintf(stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
break;
case QtWarningMsg:
fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
break;
case QtCriticalMsg:
fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
break;
case QtFatalMsg:
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function);
break;
}
}
int main(int argc, char **argv)
{
qInstallMessageHandler(myMessageOutput);
QApplication app(argc, argv);
...
return app.exec();
}
14、bool qIsFinite(double d) / bool qIsFinite(float d)
d 是否有限数。
bool qIsInf(double d) / bool qIsInf(float d)
d 是否等于无穷大。
15、bool qIsNaN(double d) / bool qIsNaN(float f)
如果 d 不是数字 (NaN),则返回 true。
16、template <typename T> const T &qMax(const T &a, const T &b)
template <typename T> const T &qMin(const T &a, const T &b)
最大值、最小值。
17、qint64 qRound64(double d) / qint64 qRound64(float d)
将 d 四舍五入到最接近的 64 位整数。
从零舍入一半(例如 0.5 -> 1、-0.5 -> -1)。
此函数不保证高精度的正确性。
double valueA = 42949672960.3;
double valueB = 42949672960.7;
qint64 roundedValueA = qRound64(valueA);
// roundedValueA = 42949672960
qint64 roundedValueB = qRound64(valueB);
// roundedValueB = 42949672961
int qRound(double d) / int qRound(float d)
将 d 舍入到最接近的整数。
此函数不保证高精度的正确性。
double valueA = 2.3;
double valueB = 2.7;
int roundedValueA = qRound(valueA);
// roundedValueA = 2
int roundedValueB = qRound(valueB);
// roundedValueB = 3
18、void qSetMessagePattern(const QString &pattern)
更改默认消息处理程序的输出。仅debug模式有效。
允许调整 qDebug()、qInfo()、qWarning()、qCritical() 和 qFatal() 的输出。qCDebug()、qCInfo()、qCWarning() 和 qCCritical() 的类别日志输出也被格式化。
支持以下占位符:
- %{appname}:QCoreApplication::applicationName()
- %{category}:日志类别
- %{file}:源文件路径
- %{function}:函数
- %{line}:源文件中的行
- %{message}:消息内容
- %{pid}:QCoreApplication::applicationPid()
- %{threadid}:当前线程的全系统ID
- %{qthreadptr}:指向当前 QThread 的指针(QThread::currentThread() 的结果)
- %{type}:"debug", "warning", "critical" 或 "fatal"
- %{time process}:消息的时间,自进程开始以来的秒数
- %{time boot}:消息的时间,以系统启动后的秒数为单位。如果无法获得启动后的时间,则输出不确定。
- %{time [format]}:消息发生时的系统时间,通过将格式传递给 QDateTime::toString() 来格式化。如果未指定格式,则使用 Qt::ISODate 的格式。
- %{backtrace [depth=N] [separator="..."]}:略。
还可以使用条件占位符:
- %{if-debug}
- %{if-info}
- %{if-warning}
- %{if-critical}
- %{if-fatal}
后跟一个 %{endif}。 %{if-*} 和 %{endif} 中的内容只有在类型匹配时才会打印。
19、template <typename Enum> std::underlying_type_t<Enum> qToUnderlying(Enum e)
将枚举数 e 转换为其枚举的基础类型中表示的等效值。
20、const char *qVersion()
在运行时以字符串形式返回 Qt 的版本号(例如,“4.1.2”)。
21、template <typename T> T * q_check_ptr(T *p)
在 p 上使用 Q_CHECK_PTR,然后返回 p。这可以用作 Q_CHECK_PTR 的内联版本。
22、QString qtTrId(const char *id, int n = -1)
返回由 id 标识的翻译字符串。 如果没有找到匹配的字符串,则返回 id 本身。
如果 n >= 0,则结果字符串中所有出现的 %n 将替换为 n 的十进制表示。 此外,根据 n 的值,翻译文本可能会有所不同。
四、实用宏成员
1、QT_NO_DEPRECATED_WARNINGS
此宏可用于抑制使用已弃用 API 时会生成的弃用警告。
2、QT_REQUIRE_VERSION(int argc, char **argv, const char *version)
此宏可用于确保应用程序是针对足够新的 Qt 版本运行的。 如果应用程序依赖于错误修复版本(例如 4.0.2)中引入的特定错误修复,这将特别有用。
argc 和 argv 参数是 main() 函数的 argc 和 argv 参数。 version 参数是一个字符串文字,用于指定应用程序需要哪个 Qt 版本(例如,“4.0.2”)。
#include <QApplication>
#include <QMessageBox>
int main(int argc, char *argv[])
{
QT_REQUIRE_VERSION(argc, argv, "4.0.2")
QApplication app(argc, argv);
...
return app.exec();
}
3、QT_VERSION
这个宏扩展了一个 0xMMNNPP(MM = 主要,NN = 次要,PP = 补丁)形式的数值,它指定了 Qt 的版本号。 例如,如果针对 Qt 4.1.2 编译的应用程序,QT_VERSION 宏将扩展为 0x040102。
可以使用 QT_VERSION 来使用可用的最新 Qt 功能。
#if QT_VERSION >= 0x040100
QIcon icon = style()->standardIcon(QStyle::SP_TrashIcon);
#else
QPixmap pixmap = style()->standardPixmap(QStyle::SP_TrashIcon);
QIcon icon(pixmap);
#endif
4、QT_VERSION_CHECK
将版本的主要、次要和补丁号转换为整数,0xMMNNPP(MM = 主要,NN = 次要,PP = 补丁)。 这可以与另一个类似处理的版本 ID 进行比较。
#include <QtGlobal>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
#include <QtWidgets>
#else
#include <QtGui>
#endif
5、QT_VERSION_STR
此宏扩展为一个字符串,指定 Qt 的版本号(例如,“4.1.2”)。这是编译应用程序所针对的版本。
6、void Q_ASSERT(bool test)
如果 test 为 false,则打印包含源代码文件名和行号的警告消息。
Q_ASSERT() 可用于在开发过程中测试前置和后置条件。 如果在编译期间定义了 QT_NO_DEBUG,则它什么也不做。
// File: div.cpp
#include <QtGlobal>
int divide(int a, int b)
{
Q_ASSERT(b != 0);
return a / b;
}
如果 b 为零,Q_ASSERT 语句将使用 qFatal() 函数输出以下消息:
ASSERT: "b != 0" in file div.cpp, line 7
void Q_ASSERT_X(bool test, const char *where, const char *what)
如果 test 为 false,则打印消息 what 以及位置、源文件名和行号。
Q_ASSERT_X 可用于在开发过程中测试前置和后置条件。 如果在编译期间定义了 QT_NO_DEBUG,则它什么也不做。
// File: div.cpp
#include <QtGlobal>
int divide(int a, int b)
{
Q_ASSERT_X(b != 0, "divide", "division by zero");
return a / b;
}
如果 b 为零,Q_ASSERT_X 语句将使用 qFatal() 函数输出以下消息:
ASSERT failure in divide: "division by zero", file div.cpp, line 7
7、void Q_ASSUME(bool expr)
使编译器假定 expr 为真。该宏通过向编译器提供有关它不知道的条件的提示,可用于改进代码生成。但是,不能保证编译器会实际使用这些提示。
这个宏可以被认为是 Q_ASSERT() 的“轻量级”版本。如果条件为假,Q_ASSERT 将中止程序的执行,Q_ASSUME 将告诉编译器不要为这些条件生成代码。因此,重要的是假设始终成立,否则可能会出现未定义的行为。
如果 expr 是一个持续为假的条件,Q_ASSUME 将告诉编译器当前代码执行无法到达。也就是说,Q_ASSUME(false) 等价于 Q_UNREACHABLE()。
Q_LIKELY() 告诉编译器该表达式是可能的,但不是唯一的可能性。 Q_ASSUME 告诉编译器这是唯一的可能性。
8、判断程序编译器的宏
- Q_CC_BOR:Borland/Turbo C++
- Q_CC_CDS:Reliant C++
- Q_CC_CLANG:Clang
- Q_CC_COMEAU:Comeau C++
- Q_CC_DEC:DEC C++
- Q_CC_EDG:Edison Design Group C++
- Q_CC_GHS:Green Hills Optimizing C++
- Q_CC_GNU:GNU C++
- Q_CC_HIGHC:MetaWare High C/C++
- Q_CC_HPACC:HP aC++
- Q_CC_INTEL:面向 Linux 的英特尔 C++、面向 Windows 的英特尔 C++
- Q_CC_KAI:KAI C++
- Q_CC_MIPS:MIPSpro C++
- Q_CC_MSVC:Microsoft Visual C/C++、Intel C++ for Windows
- Q_CC_OC:CenterLine C++
- Q_CC_PGI:Portland Group C++
- Q_CC_SUN:Sun Studio C++
- Q_CC_SYM:Digital Mars C/C++
- Q_CC_USLC:SCO OUDK 和 UDK
- Q_CC_WAT:Watcom C++
9、void Q_CHECK_PTR(void *pointer)
如果pointer为 nullptr,则打印一条消息,其中包含源代码的文件名和行号,表示程序内存不足并中止程序执行。如果启用了异常,它会抛出 std::bad_alloc 。
如果在编译期间定义了 QT_NO_DEBUG 和 QT_NO_EXCEPTIONS,则 Q_CHECK_PTR 什么也不做。因此不能使用 Q_CHECK_PTR 来检查成功的内存分配,因为在某些情况下检查将被禁用。
int *a;
Q_CHECK_PTR(a = new int[80]); // 错误用法
a = new (nothrow) int[80]; // 正确用法
Q_CHECK_PTR(a);
10、Q_DECLARE_TYPEINFO(Type, Flags) 【实用】
可以使用此宏来指定有关自定义类型 Type 的信息。有了准确的类型信息,Qt 的通用容器就可以选择合适的存储方法和算法。
Flags可以是以下之一:
- Q_PRIMITIVE_TYPE:指定 Type 是没有构造函数或析构函数的类型,并且 memcpy()为其创建了对象的有效独立副本。
- Q_RELOCATABLE_TYPE:指定 Type 具有构造函数和/或析构函数,但可以使用 memcpy() 在内存中移动数据。
- Q_MOVABLE_TYPE:与 Q_RELOCATABLE_TYPE 相同。更喜欢在新代码中使用 Q_RELOCATABLE_TYPE。 注意:尽管名称如此,但这与移动构造函数或 C++ 移动语义无关。
- Q_COMPLEX_TYPE:(默认值)指定 Type 具有构造函数和/或析构函数,并且它不能在内存中移动。
例1:
struct Point2D
{
int x;
int y;
};
Q_DECLARE_TYPEINFO(Point2D, Q_PRIMITIVE_TYPE);
例2:
class Point2D
{
public:
Point2D() { data = new int[2]; }
Point2D(const Point2D &other) { ... }
~Point2D() { delete[] data; }
Point2D &operator=(const Point2D &other) { ... }
int x() const { return data[0]; }
int y() const { return data[1]; }
private:
int *data;
};
Q_DECLARE_TYPEINFO(Point2D, Q_RELOCATABLE_TYPE);
11、Q_DECL_CONSTEXPR
此宏可用于声明应在编译时构造的变量,或可在编译时计算的内联函数。
如果使用的编译器支持该 C++11 关键字,则它会扩展为“constexpr”,否则将扩展为“constexpr”。
12、Q_DECL_EXPORT
此宏标记共享库导出的符号。
13、Q_DECL_IMPORT
此宏将符号声明为从共享库导入。
14、Q_DECL_NOEXCEPT
此宏将一个函数标记为从不抛出异常。如果函数仍然抛出异常,则定义行为:调用 std::terminate()。
宏扩展为 C++11 noexcept(如果可用)。
如果不需要 C++11 noexcept 语义,如你的函数不可能抛出异常,则不要使用这个宏,而是使用 Q_DECL_NOTHROW。
15、Q_DECL_NOEXCEPT_EXPR(x)
如果 x 为真,此宏将函数标记为不抛出异常。 如果函数仍然抛出异常,则定义行为:调用 std::terminate()。
如果可用,宏扩展为 C++11 noexcept(x)。
如果不需要 C++11 noexcept 语义,如你的函数不可能抛出异常,则不要使用这个宏,而是使用 Q_DECL_NOTHROW。
16、Q_DECL_NOTHROW
此宏在任何情况下都将函数标记为从不抛出异常。如果函数仍然抛出异常,则行为未定义。
17、Q_FOREVER
forever
提供此宏是为了方便编写无限循环。
forever {
...
}
它等价于 for (;;)。
可以通过将以下行添加到 .pro 文件来禁用此宏:
CONFIG += no_keywords
18、const char * Q_FUNC_INFO
扩展为描述宏所在函数的字符串。该字符串的具体内容取决于编译器。对于 GNU GCC,它通常是函数签名,而对于其他编译器,它可能是行号和列号。
如果在函数外部使用此宏,则行为未定义。
Q_FUNC_INFO 可以方便地与 qDebug() 一起使用。例如:
template<typename TInputType>
const TInputType &myMin(const TInputType &value1, const TInputType &value2)
{
qDebug() << Q_FUNC_INFO << "was called with value1:" << value1 << "value2:" << value2;
if(value1 < value2)
return value1;
else
return value2;
}
19、qint64 Q_INT64_C(literal) / quint64 Q_UINT64_C(literal)
以独立于平台的方式包装有符号的 64 位整数 / 无符号整数。
qint64 value = Q_INT64_C(932838457459459);
20、Q_LIKELY(expr) 【实用】
向编译器提示所包含的条件 expr 的计算结果可能为真。使用此宏可以帮助编译器优化代码。
// // “if”中的条件在大多数情况下都为true
for (int i = 1; i <= 365; i++) {
if (Q_LIKELY(isWorkingDay(i))) {
...
}
...
}
Q_UNLIKELY(expr)
向编译器提示封闭条件 expr 的计算结果可能为假。使用这个宏可以帮助编译器优化代码。
bool readConfiguration(const QFile &file)
{
// We expect to be asked to read an existing file
if (Q_UNLIKELY(!file.exists())) {
qWarning() << "File not found";
return false;
}
...
return true;
}
21、判断系统的宏
- Q_OS_AIX:AIX
- Q_OS_ANDROID;Android
- Q_OS_BSD4:BSD 4.4
- Q_OS_CYGWIN:Cygwin
- Q_OS_DARWIN:基于 Darwin 的操作系统,例如 macOS、iOS、watchOS 和 tvOS。
- Q_OS_FREEBSD:FreeBSD
- Q_OS_HPUX:HP-UX
- Q_OS_HURD:GNU Hurd
- Q_OS_IOS:iOS
- Q_OS_LINUX:Linux
- Q_OS_LYNX:LynxOS
- Q_OS_MAC:不推荐使用的 Q_OS_DARWIN 的同义词。
- Q_OS_MACOS:macOS
- Q_OS_NETBSD:NetBSD
- Q_OS_OPENBSD:OpenBSD
- Q_OS_OSX:不推荐使用的 Q_OS_MACOS 的同义词。
- Q_OS_QNX:QNX Neutrino
- Q_OS_SOLARIS:Sun Solaris
- Q_OS_TVOS:tvOS
- Q_OS_UNIX:UNIX BSD/SYSV
- Q_OS_WASM:WebAssembly
- Q_OS_WATCHOS:watchOS
- Q_OS_WIN32:32 位和 64 位版本的 Windows
- Q_OS_WIN64:64 位版本的 Windows
- Q_OS_WIN:所有受支持的 Windows 版本
- Q_OS_WINDOWS:Q_OS_WIN 的同义词
22、判断编译程序的处理器的宏
- Q_PROCESSOR_X86:x86 处理器
- Q_PROCESSOR_S390:S/390 处理器
- Q_PROCESSOR_ALPHA:Alpha 处理器
- Q_PROCESSOR_ARM:ARM 处理器
- Q_PROCESSOR_ARM_V5:ARMv5 处理器
- Q_PROCESSOR_ARM_V6:ARMv6 处理器
- Q_PROCESSOR_ARM_V7:ARMv7 处理器
- Q_PROCESSOR_AVR32:AVR32 处理器
- Q_PROCESSOR_BLACKFIN:Blackfin 处理器
- Q_PROCESSOR_IA64:IA-64 处理器
- Q_PROCESSOR_MIPS:MIPS 处理器
- Q_PROCESSOR_MIPS_32:MIPS32 处理器
- Q_PROCESSOR_MIPS_64:MIPS64 处理器
- Q_PROCESSOR_MIPS_I:MIPS-I 处理器
- Q_PROCESSOR_MIPS_II:MIPS-II 处理器
- Q_PROCESSOR_MIPS_III:MIPS-III 处理器
- Q_PROCESSOR_MIPS_IV:MIPS-IV 处理器
- Q_PROCESSOR_MIPS_V:MIPS-V 处理器
- Q_PROCESSOR_POWER:POWER 处理器
- Q_PROCESSOR_POWER_32:32 位 Power 处理器
- Q_PROCESSOR_POWER_64:64 位 Power 处理器
- Q_PROCESSOR_RISCV:RISC-V 处理器
- Q_PROCESSOR_RISCV_32:32 位 RISC-V 处理器
- Q_PROCESSOR_RISCV_64:64 位 RISC-V 处理器
- Q_PROCESSOR_S390_X:S/390x 处理器
- Q_PROCESSOR_SH:SuperH 处理器
- Q_PROCESSOR_SH_4A:SuperH 4A 处理器
- Q_PROCESSOR_SPARC:SPARC 处理器
- Q_PROCESSOR_SPARC_V9:SPARC V9 处理器
- Q_PROCESSOR_X86_32:32 位 x86 处理器。这包括所有 i386、i486、i586 和 i686 处理器。
- Q_PROCESSOR_X86_64:64 位 x86 处理器编译。这包括所有 AMD64、Intel 64 和其他 x86_64/x64 处理器。
23、void Q_UNREACHABLE
标记不可能的条件。告诉编译器任何执行都无法到达当前点。
enum Shapes {
Rectangle,
Triangle,
Circle,
NumShapes
};
...
switch (shape) {
case Rectangle:
return rectangle();
case Triangle:
return triangle();
case Circle:
return circle();
case NumShapes:
Q_UNREACHABLE();
break;
}
插入 Q_UNREACHABLE() 的优点是编译器被告知不要为包含该值的形状变量生成代码。如果缺少宏,编译器仍会为该值生成必要的比较。 如果删除了 case 标签,一些编译器可能会产生警告,指出某些枚举值没有被检查。
24、Q_UNUSED(name)
向编译器指示函数体中未使用具有指定名称的参数。这可用于抑制编译器警告。
25、const char * qPrintable(const QString &str)
将 str 作为 const char * 返回。 这相当于 str.toLocal8Bit().constData()。
在使用 qPrintable() 的语句之后,char 指针将无效。这是因为 QString::toLocal8Bit() 返回的数组将超出范围。
注意:qDebug()、qInfo()、qWarning()、qCritical()、qFatal() 期望 %s 参数为 UTF-8 编码,而 qPrintable() 转换为本地 8 位编码。 因此,应该使用 qUtf8Printable() 而不是 qPrintable() 来记录字符串。
const char *qUtf8Printable(const QString &str)
将 str 作为 const char * 返回。 这相当于 str.toUtf8().constData()。
在使用 qUtf8Printable() 的语句之后,char 指针将无效。 这是因为 QString::toUtf8() 返回的数组将超出范围。
qWarning("%s: %s", qUtf8Printable(key), qUtf8Printable(value));
const wchar_t *qUtf16Printable(const QString &str)
将 str 作为 const ushort * 返回,但转换为 const wchar_t * 以避免出现警告。 这相当于 str.utf16() 加上一些转换。
此宏的返回值唯一有用的就是将它传递给 QString::asprintf() 以用于 %ls 转换。特别是,返回值不是有效的 const wchar_t*的情况。
一般情况下,在使用了 qUtf16Printable() 的语句之后,指针就会失效。 这是因为指针可能是从临时表达式中获得的,这将超出范围。