QVariant这个类可以说是一个万能数据类型存储对象类,我们可以使用这个类型存储我们需要的任何数据。那么它到底是如何存储数据的呢?
查看QVariant头文件,可以发现对于比较常见的类型例如int、bool、QString等,QVariant提供了对应的构造函数,我们可以直接调用构造函数来把数据存储到一个QVariant变量中:
int num = 10;
QVariant varInt(num);
QString str = "qwer";
QVariant varQString(str);
以int类型和QString类型为例,二者对应的QVariant构造函数实现如下:
QVariant::QVariant(int val)
: d(Int)
{ d.data.i = val; }
先看int类型对应的构造函数,可以看到只对成员变量d进行了操作。查看d的定义,发现d为Private类型,而Private的定义如下:
其中,union联合体Data用于保存数据,包含基本类型和QObject *、void *、PrivateShared *;type用于存储数据的类型,is_shared表示数据是否共享,is_null表示数据是否为空。
那么int类型对应的QVariant构造函数就把d.type即存储的数据类型设置为了Int,同时直接把int值保存到d.data.i联合体中。
下面再看QString类型对应的构造函数:
QVariant::QVariant(const QString &val)
: d(String)
{ v_construct<QString>(&d, val); }
可以发现除了给d.type赋值为String外,还调用了v_construct函数。对源代码追溯如下:
template <class T>
inline void v_construct(QVariant::Private *x, const T &t)
{
// dispatch
v_construct_helper(x, t, typename QVariantIntegrator<T>::CanUseInternalSpace_t());
}
template<typename T>
struct QVariantIntegrator
{
static const bool CanUseInternalSpace = sizeof(T) <= sizeof(QVariant::Private::Data)
&& ((QTypeInfoQuery<T>::isRelocatable) || std::is_enum<T>