QVariant使用自定义类型的例子
#include <QCoreApplication>
#include <QVariant>
#include <QString>
#include <QDebug>
void Test();
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Test();
return a.exec();
}
class Cup
{
public:
QString material;
};
Q_DECLARE_METATYPE(Cup)
void Test()
{
Cup cup1;
cup1.material = "steel";
QVariant q1;
q1.setValue(cup1);
//内部复制cup1对象,复制的对象为堆对象,保存在d->data.shared中
//d->is_shared = true;
//d->data.shared = new QVariant::PrivateShared(ptr);
//const void *QVariant::constData() const
//{
// return d.is_shared ? d.data.shared->ptr : reinterpret_cast<const void *>(&d.data.ptr);
//}
//template<typename T>
//inline T value() const
//{ return qvariant_cast<T>(*this); }
//qvariant_cast函数最终调用 constData函数获得之前复制的对象的指针,再转变成T类型的实例
Cup cup2 = q1.value<Cup>();
qDebug()<<cup2.material;
}
QVariant保存用户类型的机制的源码分析如下,源码版本为你5.3。
template<typename T>
inline void QVariant::setValue(const T &avalue)
{ qVariantSetValue(*this, avalue); }
template <typename T>
inline void qVariantSetValue(QVariant &v, const T &t)
{
//if possible we reuse the current QVariant private
const uint type = qMetaTypeId<T>();
QVariant::Private &d = v.data_ptr();
if (v.isDetached() && (type == d.type || (type <= uint(QVariant::Char) && d.type <= uint(QVariant::Char)))) {
.........
} else {
v = QVariant(type, &t, QTypeInfo<T>::isPointer); //进入此分支
}
}
template <typename T>
inline Q_DECL_CONSTEXPR int qMetaTypeId()
{
Q_STATIC_ASSERT_X(QMetaTypeId2<T>::Defined, "Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system");
return QMetaTypeId2<T>::qt_metatype_id();
}
template <typename T>
struct QMetaTypeId2
{
enum { Defined = QMetaTypeId<T>::Defined, IsBuiltIn=false };
static inline Q_DECL_CONSTEXPR int qt_metatype_id()
{ return QMetaTypeId<T>::qt_metatype_id(); }
};
#define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
#define Q_DECLARE_METATYPE_IMPL(TYPE) \
QT_BEGIN_NAMESPACE \
template <> \
struct QMetaTypeId< TYPE > \
{ \
enum { Defined = 1 }; \
static int qt_metatype_id() \
{ \
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
if (const int id = metatype_id.loadAcquire()) \
return id;
//调用qRegisterMetaType注册用户自定义的类型 \
const int newId = qRegisterMetaType< TYPE >(#TYPE, \
reinterpret_cast< TYPE *>(quintptr(-1))); \
metatype_id.storeRelease(newId); \
return newId; \
} \
}; \
QT_END_NAMESPACE
template <typename T>
int qRegisterMetaType(const char *typeName
#ifndef Q_QDOC
, T * dummy = 0
, typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined
#endif
)
{
#ifdef QT_NO_QOBJECT
QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = typeName; //由const char *转换成字节数组
#else
QT_PREPEND_NAMESPACE(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
#endif
return qRegisterNormalizedMetaType<T>(normalizedTypeName, dummy, defined);
}
template <typename T>
int qRegisterNormalizedMetaType(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName
#ifndef Q_QDOC
, T * dummy = 0
, typename QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::DefinedType defined = QtPrivate::MetaTypeDefinedHelper<T, QMetaTypeId2<T>::Defined && !QMetaTypeId2<T>::IsBuiltIn>::Defined
#endif
)
{
.........
//QMetaTypeFunctionHelper<T>实例化了要注册类型对应的QMetaTypeFunctionHelper类
//通过此类包装,获得TYPE类的对应的Delete等函数
const int id = QMetaType::registerNormalizedType(normalizedTypeName,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Delete,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Create,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Destruct,
QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Construct,
int(sizeof(T)),
flags,
QtPrivate::MetaObjectForType<T>::value());
if (id > 0) {
QtPrivate::SequentialContainerConverterHelper<T>::registerConverter(id);
QtPrivate::AssociativeContainerConverterHelper<T>::registerConverter(id);
QtPrivate::MetaTypePairHelper<T>::registerConverter(id);
QtPrivate::MetaTypeSmartPointerHelper<T>::registerConverter(id);
}
return id;
}
int QMetaType::registerNormalizedType(const NS(QByteArray) &normalizedTypeName, Deleter deleter,
Creator creator,
Destructor destructor,
Constructor constructor,
int size, TypeFlags flags, const QMetaObject *metaObject)
{
//<普通的参数合法性检查>
QVector<QCustomTypeInfo> *ct = customTypes();
if (!ct || normalizedTypeName.isEmpty() || !deleter || !creator || !destructor || !constructor)
return -1;
//</普通的参数合法性检查>
//查找内建的支持的类型
//自定义的类型名normalizedTypeName.constData()
//自定义的类型名的字符串长度normalizedTypeName.size()
int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
normalizedTypeName.size());
int previousSize = 0;
int previousFlags = 0;
//用户自定义类型 进入此if
if (idx == UnknownType) {
QWriteLocker locker(customTypesLock());
//在自定义类型中查找 看是否注册过
idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
normalizedTypeName.size());
if (idx == UnknownType) {//未注册过 所以注册
QCustomTypeInfo inf;
inf.typeName = normalizedTypeName;
inf.creator = creator;
inf.deleter = deleter;
#ifndef QT_NO_DATASTREAM
inf.loadOp = 0;
inf.saveOp = 0;
#endif
inf.alias = -1;
inf.constructor = constructor;
inf.destructor = destructor;
inf.size = size;
inf.flags = flags;
inf.metaObject = metaObject;
idx = ct->size() + User;
ct->append(inf); //完成注册
return idx;
}
if (idx >= User) {
previousSize = ct->at(idx - User).size;
previousFlags = ct->at(idx - User).flags;
}
}
.........
return idx;
}
namespace QtMetaTypePrivate {
template <typename T, bool Accepted = true>
struct QMetaTypeFunctionHelper {
static void Delete(void *t)
{
delete static_cast<T*>(t);
}
static void *Create(const void *t)
{
if (t)
return new T(*static_cast<const T*>(t));
return new T();
}
static void Destruct(void *t)
{
Q_UNUSED(t) // Silence MSVC that warns for POD types.
static_cast<T*>(t)->~T();
}
static void *Construct(void *where, const void *t)
{
if (t)
return new (where) T(*static_cast<const T*>(t));
return new (where) T;
}
//.........
};