QList如何决定是存储指针还是存储项目本身

How does QList decide whether to store pointers or the items themselves?

本文关键字:存储 指针 项目 何决定 决定 QList      更新时间:2023-10-16

来自文档:

在内部,QList表示为指向项的指针数组如果T本身是指针类型或基本类型大于指针,或者如果T是Qt的共享类之一,那么QList将项目直接存储在指针数组中。

我很想知道,QList是如何根据类型"决定"是存储指针还是存储项本身的?

他们是不是使用了一些深奥的模板语法?

让我们阅读源代码(我使用的是Qt 4.8)。

qlist.h

struct Node { 
    void *v;
#if defined(Q_CC_BOR)
    Q_INLINE_TEMPLATE T &t();
#else
    Q_INLINE_TEMPLATE T &t()
    { return *reinterpret_cast<T*>(QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic
                                   ? v : this); }
#endif
};

QList使用QTypeInfo来确定类型属性。CCD_ 4是为各种类型单独声明的。在qglobal.h中:

未知类型的默认声明:

template <typename T>
class QTypeInfo
{
public:
    enum {
        isPointer = false,
        isComplex = true,
        isStatic = true,
        isLarge = (sizeof(T)>sizeof(void*)),
        isDummy = false
    };
};

指针声明:

template <typename T>
class QTypeInfo<T*>
{
public:
    enum {
        isPointer = true,
        isComplex = false,
        isStatic = false,
        isLarge = false,
        isDummy = false
    };
};

用于方便类型信息声明的宏:

#define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) 
class QTypeInfo<TYPE > 
{ 
public: 
    enum { 
        isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0), 
        isStatic = (((FLAGS) & (Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE)) == 0), 
        isLarge = (sizeof(TYPE)>sizeof(void*)), 
        isPointer = false, 
        isDummy = (((FLAGS) & Q_DUMMY_TYPE) != 0) 
    }; 
    static inline const char *name() { return #TYPE; } 
}
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS) 
template<> 
Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)

基元类型的声明:

Q_DECLARE_TYPEINFO(bool, Q_PRIMITIVE_TYPE);
Q_DECLARE_TYPEINFO(char, Q_PRIMITIVE_TYPE); /* ... */

此外,它还为特定的Qt类型定义,例如在qurl.h中:

Q_DECLARE_TYPEINFO(QUrl, Q_MOVABLE_TYPE);

或者在qhash.h中:

Q_DECLARE_TYPEINFO(QHashDummyValue, Q_MOVABLE_TYPE | Q_DUMMY_TYPE);

QList使用QTypeInfo<T>时,编译器会选取最接近的当前QTypeInfo定义。