QT6 源(13):QT类 里重要的基础类 QMetaEnum 的源码定义及重要成员函数的注释,以及宏定义 Q_DECLARE_TYPEINFO ( Type , Flags )规范类的存储类型

(1)类 QMetaEnum 的定义,包含 #include 《QMetaProperty》 即可找到:

先看一下本类概述:

在这里插入图片描述

++ 源码

class Q_CORE_EXPORT QMetaEnum //本类提供有关枚举器的元数据。
{
private:
    struct Data {
        enum { Size = 5 };
        const uint * d;
        quint32  name() const { return d[0]; }
        quint32 alias() const { return d[1]; }
        quint32 flags() const { return d[2]; }
        qint32 keyCount() const { return static_cast<qint32>(d[3]); }
        quint32 data() const  { return d[4]; }  
    };
    Data data;   //本元枚举类定义的数据成员
    const QMetaObject * mobj;

    QMetaEnum(const QMetaObject *mobj, int index); //构造函数
    friend struct QMetaObject;
    friend struct QMetaObjectPrivate;
    
public:  //默认初始化数据成员为控制
    constexpr inline QMetaEnum() : mobj(nullptr), data({ nullptr }) {}

    const char * name() const;  //返回类型的名称(不包括作用域)
	//例如,Qt::Key 枚举的类型名为 Key,作用域为 Qt。
	//对于标志,它返回标志类型的名称,而不是枚举类型的名称。
	
    const char * enumName() const;//返回标志的枚举名称(不包括范围)
	//例如,Qt:AlignmentFlag标志具有 AlignmentFlag作为枚举名称,但 Alignment作为类型名称。
	//非标志枚举具有相同的类型和枚举名称。枚举名称与类型名称具有相同的范围。
	
    bool isFlag() const; //如果此枚举器用作标志,则返回 true;否则返回 false。
	//当用作标志时,枚举器可以使用 OR 运算符组合。
	
    bool isScoped() const; //若此枚举器声明为 C++11枚举类,则返回 true;否则返回 false。
	const char * scope() const; //返回枚举者声明的上下文范围。scope 范围
	//列如,Qt::AlignmentFlag 枚举的别名 scope 是 Qt,名称是 AlignmentFlag。
	
 	inline bool isValid() const { return name() != nullptr; }
 	//如果此枚举有效(具有名称),则返回true;否则返回 false。
 	
    int keyCount() const; // Returns the number of keys.

    const char * key(int index) const;
    //Returns the key with the given index, or nullptr if no such key exists
    int        value(int index) const;
    //Returns the value with the given index; or returns -1 if there is no such value.

    int keyToValue(const char * key, bool * ok = nullptr) const; // ok用于返回值
    //返回给定枚举键的整数值,如果键未定义则返回-1。   //  a=5 则 key = a,value = 5 
	//如果未定义 key,则 *ok 设置为 false;否则 *ok 设置为 true。
    int keysToValue(const char *keys, bool *ok = nullptr) const; //带 flag 标志
    //返回使用 OR 运算符将键的值组合在一起得出的值,如果键未定义则为-1。
    //请注意,键中的字符串必须以“|”分隔。 keys 包含多个字符串,之间以 | 分割
	//如果未定义 keys,则 *ok 设置为 false;否则 *ok 设置为 true。

    const char * valueToKey(int value) const; //适用于普通枚举
    //返回用作给定枚举值的名称的字符串,如果未定义值则为 nullptr。
    QByteArray valueToKeys(int value) const;//要求枚举同时用 Q_FLAG声明,以支持位运算。
    //返回一个以 | 分隔的字节数组,表示给定的值。因为会返回被 or 运算组合到一起的多个名字
    //Returns a byte array of '|'-separated keys that represents the given value.

	//返回内部包裹的 QMetaObject * 数据成员
    inline const QMetaObject * enclosingMetaObject() const { return mobj; }
	
	//返回与模板参数类型相对应的 QMetaEnum。枚举需要使用 QENUM进行声明。
    template<typename T>
    static QMetaEnum fromType()  //静态成员函数,返回值还是本类型
    {
        static_assert(QtPrivate::IsQEnumHelper<T>::Value,
                      "QMetaEnum::fromType only works with enums declared as "
                      "Q_ENUM, Q_ENUM_NS, Q_FLAG or Q_FLAG_NS");
        const QMetaObject * metaObject = qt_getEnumMetaObject(T());
        const char * name = qt_getEnumName(T());
        return metaObject->enumerator(metaObject->indexOfEnumerator(name));
    }
};
Q_DECLARE_TYPEINFO(QMetaEnum, Q_RELOCATABLE_TYPE);

(2)解释下上面源码里出现的宏 Q_DECLARE_TYPEINFO ,先给出其官方的英文注释:

在这里插入图片描述

++ 给出其源码

/* Specialize a specific type with:   Q_DECLARE_TYPEINFO(type, flags);

   where 'type' is the name of the type to specialize and 'flags' is
   logically-OR'ed combination of the flags below.*/
   
enum { /* TYPEINFO flags */
    Q_COMPLEX_TYPE     = 0,
    Q_PRIMITIVE_TYPE   = 0x1,
    Q_RELOCATABLE_TYPE = 0x2,
    Q_MOVABLE_TYPE     = 0x2,
    Q_DUMMY_TYPE       = 0x4,
};

#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) \
class QTypeInfo<TYPE > \
{ \
public: \
    enum { \
        isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0) && !std::is_trivial_v<TYPE>, \
        isRelocatable = !isComplex || ((FLAGS) & Q_RELOCATABLE_TYPE) || qIsRelocatable<TYPE>, \
        isPointer = false, \
        isIntegral = std::is_integral< TYPE >::value, \
    }; \
}

#define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \
template<> \
Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)

/* Specialize QTypeInfo for QFlags<T> */
template<typename T>
 class QFlags;
 
template<typename T>  // 此模板函数已经没有定义了,跟踪到此为止,但结合注释也够用了
Q_DECLARE_TYPEINFO_BODY(QFlags<T>, Q_PRIMITIVE_TYPE);

(3)

谢谢

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangzhangkeji

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值