qglobal.h

当我追踪到qglobal.h的时候,我认为我可以停下来了,因为这里出现了语句

#ifdef __cplusplus
#  include <type_traits>
#  include <cstddef>
#  include <utility>
#endif
#ifndef __ASSEMBLER__
#  include <stddef.h>
#endif

其中 <type_traits> <cstddef> <utility>是c++核心的头文件,<stddef.h>是gcc所需的头文件,看起来应该是qt自己改写了其中里面一部分,我想,这里应该是Qt设计者代码框架的初始位置。

但是往后读发现它还包含了头文件qconfig.h和qtcore-config.h,进去看了一下,里面主要是qt版本和编译相关的宏定义,真是学到了,原来大程序都是这样开始的,以宏定义开始,这下真的是Qt的源头了,两个config的头文件。

#ifdef _MSC_VER
#  define QT_SUPPORTS(FEATURE) (!defined QT_NO_##FEATURE)
#else
#  define QT_SUPPORTS(FEATURE) (!defined(QT_NO_##FEATURE))
#endif

这个宏定义出现了我们不长见到的##(两连#),什么意思呢,就是把##后面的内容与前面的内容连在一起,而#则表示把后面的内容转换为字符串,我百度了一段代码

#include <stdio.h>
#define f(a,b) a##b
#define g(a)   #a
#define h(a) g(a)
int main()
{
        printf("%s\n", h(f(1,2)));   // 12
        printf("%s\n", g(f(1,2))); // f(1,2)
        return 0;
}

很明显了哈。

接着看,竟然又包含了三个头文件

#include <QtCore/qsystemdetection.h>
#include <QtCore/qprocessordetection.h>
#include <QtCore/qcompilerdetection.h>

依次进去看了一下,首先是qsystemdetection.h里面写了一些关于系统(各类系统)的宏定义标识,然后qprocessordetection.h里面写出了关于处理器(各类处理器)的一些标识,在这里面提到了一个计算机知识,即BE(高位编址)和LE(低位编址),最后看了qcompilerdetection.h,里面出现了程序员最熟悉的各类编译器的宏定义,可怕,我一定要贴出来,因为我很多都没听说过,Qt支持的编译器应该就在这里了

The compiler, must be one of: (Q_CC_x)

     SYM      - Digital Mars C/C++ (used to be Symantec C++)
     MSVC     - Microsoft Visual C/C++, Intel C++ for Windows
     BOR      - Borland/Turbo C++
     WAT      - Watcom C++
     GNU      - GNU C++
     COMEAU   - Comeau C++
     EDG      - Edison Design Group C++
     OC       - CenterLine C++
     SUN      - Forte Developer, or Sun Studio C++
     MIPS     - MIPSpro C++
     DEC      - DEC C++
     HPACC    - HP aC++
     USLC     - SCO OUDK and UDK
     CDS      - Reliant C++
     KAI      - KAI C++
     INTEL    - Intel C++ for Linux, Intel C++ for Windows
     HIGHC    - MetaWare High C/C++
     PGI      - Portland Group C++
     GHS      - Green Hills Optimizing C++ Compilers
     RVCT     - ARM Realview Compiler Suite
     CLANG    - C++ front-end for the LLVM compiler

多说一点,这里还出现了一个我几乎不敢写的方式,在这三个头文件里面,竟然有如下语句:

#ifndef QGLOBAL_H
# include <QtCore/qglobal.h>
#endif

意味着相互包含,虽然有宏定义去解决这个问题,可是想想还是背脊发凉,我真的不敢这么写,这次看了可以给自己壮壮胆了。

后面包含了C++的最爱:

#include <algorithm>

 后面出现了匪夷所思的宏定义,我自己认为没必要,好想找个人讨论下,接我疑惑

# define QT_FORWARD_DECLARE_CLASS(name) class name;
# define QT_FORWARD_DECLARE_STRUCT(name) struct name;
# define QT_MANGLE_NAMESPACE(name) name

 下面这个宏定义真是:

# define QT_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
# define QT_USE_NAMESPACE using namespace ::QT_NAMESPACE;
# define QT_BEGIN_NAMESPACE namespace QT_NAMESPACE {
# define QT_END_NAMESPACE }
# define QT_BEGIN_INCLUDE_NAMESPACE }
# define QT_END_INCLUDE_NAMESPACE namespace QT_NAMESPACE {
#ifndef QT_BEGIN_MOC_NAMESPACE
# define QT_BEGIN_MOC_NAMESPACE QT_USE_NAMESPACE

有种感觉,这种大框架的写法都是和普通程序的写法有区别的。

下面这个好像解答了我上面的疑惑

# define QT_FORWARD_DECLARE_CLASS(name) \
    QT_BEGIN_NAMESPACE class name; QT_END_NAMESPACE \
    using QT_PREPEND_NAMESPACE(name);

当我们写了QT_FORWARD_DECLARE_CLASS(QWindow)时我来翻译一下:

namespace QT_NAMESPACE{class Window;} using ::QT_NAMESPACE::Window;

这真的很妙,因为一个宏定义完成了一个类在命名空间的声明,如果有大量这种声明,这种宏定义看起来会很省力气,减少代码,降低出错的概率。

很好,这里我又看了Qt对于基本数据类型的宏定义,其实,我觉得这是Qt想区别于其它编译器和编辑器的一种方式,我认为这真的没什么用

typedef signed char qint8;         /* 8 bit signed */
typedef unsigned char quint8;      /* 8 bit unsigned */
typedef short qint16;              /* 16 bit signed */
typedef unsigned short quint16;    /* 16 bit unsigned */
typedef int qint32;                /* 32 bit signed */
typedef unsigned int quint32;      /* 32 bit unsigned */

除了看到了关于编译lib和dll的一些控制外,看到了一个Qt关于类里面含有私有构造函数和"="重载的一些说明

/*
   Some classes do not permit copies to be made of an object. These
   classes contains a private copy constructor and assignment
   operator to disable copying (the compiler gives an error message).
*/
#define Q_DISABLE_COPY(Class) \
    Class(const Class &) Q_DECL_EQ_DELETE;\
    Class &operator=(const Class &) Q_DECL_EQ_DELETE;

看到了就记录一些,这其实是C++11里面的一个内容,就是把构造函数显示的表示出来,再在后面加上“=delete”,表示不允许使用该类型的构造函数。

看了这么多,真的想说,宏定义看起来真的很累。

struct AlignOfHelper
    {
        char c;
        T type;

        AlignOfHelper();
        ~AlignOfHelper();
    };

    template <class T>
    struct AlignOf_Default
    {
        enum { Value = sizeof(AlignOfHelper<T>) - sizeof(T) };
    };

    template <class T> struct AlignOf : AlignOf_Default<T> { };
    template <class T> struct AlignOf<T &> : AlignOf<T> {};
    template <size_t N, class T> struct AlignOf<T[N]> : AlignOf<T> {};

这真的是模板里面的内容,还涉及到模板的派生,我真的忘了这里的妙处在哪。

接下来出现了一些基础数据类型、一些实用的宏、一些实用的内联函数(基本的比较)、处理data steam的函数、QString::utf16()处理函数

贴一个这里面提到的函数

/*
   This function tests a float for a null value. It doesn't
   check whether the actual value is 0 or close to 0, but whether
   it is binary 0, disregarding sign.
*/
Q_REQUIRED_RESULT static inline Q_DECL_UNUSED bool qIsNull(float f)
{
    union U {
        float f;
        quint32 u;
    };
    U val;
    val.f = f;
    return (val.u & 0x7fffffff) == 0;
}

这里面提供了一些Warning disabled的方法

/*
   Avoid some particularly useless warnings from some stupid compilers.
   To get ALL C++ compiler warnings, define QT_CC_WARNINGS or comment out
   the line "#define QT_NO_WARNINGS".
*/
#if !defined(QT_CC_WARNINGS)
#  define QT_NO_WARNINGS
#endif
#if defined(QT_NO_WARNINGS)

后面包含了

qtypeinfo.h,这里面定义了QTypeInfo的类,就是数据类型信息的定义;

qsysinfo.h,这里面包含了操作系统的一些信息的定义;

qlogging.h这里包含了一些日志信息的定义;

qflags.h定义了类型安全的enum;

qatomic.h提供了原子操作一些底层的封装;所谓原子操作,就是要求某一操作不被打断

qnumeric.h提供了判断NaN和Inf的函数;

qgobalstatic.h 留点下次再写吧

 

 

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值