【问题标题】:How does QList decide whether to store pointers or the items themselves?QList 如何决定是存储指针还是存储项目本身?
【发布时间】:2013-07-08 11:07:18
【问题描述】:

来自docs

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

我很想知道,QList 'decide' 是如何根据类型存储指针还是项目本身?

他们是否使用一些深奥的模板语法来做到这一点?

【问题讨论】:

  • 因为您将列表定义为:QList<int>QList<int*> 甚至 QList<myBigStructureTypeThingy> 您告诉 QList 您将存储什么类型。如果此类型的大小等于或小于指针,它将存储整个变量,否则查找数组将仅包含指向变量的指针。然后列表本身将包含查找数组和数据内存区域(如果 QList)。

标签: c++ qt templates qlist


【解决方案1】:

让我们阅读源代码(我使用的是 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 来确定类型属性。 QTypeInfo 分别为各种类型声明。在 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&lt;T&gt; 时,编译器会选择当前最接近的QTypeInfo 定义。

【讨论】:

  • 所以Node::t() 是具有魔力的函数。根据QTypeInfo,它会取消引用存储的32 位值或this 指针本身。感谢您的洞察力!
猜你喜欢
  • 2017-11-05
  • 2013-03-24
  • 2012-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
相关资源
最近更新 更多