<QtGlobal> - 全局 Qt 声明

一、描述

<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() 函数生成的消息。
  • QtSystemMsgQtCriticalMsg

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)

如果成员函数也是常量重载,则需要使用 qConstOverloadqNonConstOverload

C++11-only 代码中,可以使用 QOverloadQConstOverloadQNonConstOverload

    ... 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一样。即使使用 .pro 文件的 CONFIG 变量指定了 no_keywords,该宏也可用。

       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_WINDOWSQ_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() 的语句之后,指针就会失效。 这是因为指针可能是从临时表达式中获得的,这将超出范围。

猜你喜欢

转载自blog.csdn.net/kenfan1647/article/details/121645554
今日推荐