• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Cpper
            C/C++高級工程師 Android高級軟件工程師 IT集成工程師 音頻工程師 熟悉c,c++,java,c#,py,js,asp等多種語言 程序猿
            QVariant是一種可以存儲不同類型的數(shù)據(jù)結(jié)構(gòu),在很多場合這是很有用得
            為了達到這種目的,可以想象,該對象應(yīng)該存儲對象的類型信息,數(shù)據(jù)信息以及其他輔助詳細
            考慮用途,這種對象必須支持對不同對象的存儲,對存儲類型的檢測以及取對象三個功能
            1.對象的存儲
            代碼見下:
                QVariant(Type type);
                QVariant(
            int typeOrUserType, const void *copy);
                QVariant(
            int typeOrUserType, const void *copy, uint flags);
                QVariant(
            const QVariant &other);

            #ifndef QT_NO_DATASTREAM
                QVariant(QDataStream 
            &s);
            #endif

                QVariant(
            int i);
                QVariant(
            uint ui);
                QVariant(qlonglong ll);
                QVariant(qulonglong ull);
                QVariant(
            bool b);
                QVariant(
            double d);
                QVariant(
            float f) { d.is_null = false; d.type = QMetaType::Float; d.data.f = f; }
            #ifndef QT_NO_CAST_FROM_ASCII
                QT_ASCII_CAST_WARN_CONSTRUCTOR QVariant(
            const char *str);
            #endif

                QVariant(
            const QByteArray &bytearray);
                QVariant(
            const QBitArray &bitarray);
                QVariant(
            const QString &string);
                QVariant(
            const QLatin1String &string);
                QVariant(
            const QStringList &stringlist);
                QVariant(
            const QChar &qchar);
                QVariant(
            const QDate &date);
                QVariant(
            const QTime &time);
                QVariant(
            const QDateTime &datetime);
                QVariant(
            const QList<QVariant> &list);
                QVariant(
            const QMap<QString,QVariant> &map);
                QVariant(
            const QHash<QString,QVariant> &hash);
            #ifndef QT_NO_GEOM_VARIANT
                QVariant(
            const QSize &size);
                QVariant(
            const QSizeF &size);
                QVariant(
            const QPoint &pt);
                QVariant(
            const QPointF &pt);
                QVariant(
            const QLine &line);
                QVariant(
            const QLineF &line);
                QVariant(
            const QRect &rect);
                QVariant(
            const QRectF &rect);
            #endif
                QVariant(
            const QUrl &url);
                QVariant(
            const QLocale &locale);
            #ifndef QT_NO_REGEXP
                QVariant(
            const QRegExp &regExp);
            #endif
            #ifndef QT_BOOTSTRAPPED
                QVariant(
            const QEasingCurve &easing);
            #endif
                QVariant(Qt::GlobalColor color);
            2.QVariant Type
            在該對象中type負責(zé)記錄對象的類型,這對于正確取出對象是很用得
            3.成員函數(shù)
              Type type() const;
                
            int userType() const;
                
            const char *typeName() const;

                
            bool canConvert(Type t) const;
                
            bool convert(Type t);

            #ifdef QT3_SUPPORT
                inline QT3_SUPPORT 
            bool canCast(Type t) const
                { 
            return canConvert(t); }
                inline QT3_SUPPORT 
            bool cast(Type t)
                { 
            return convert(t); }
            #endif
            這幾個函數(shù)的用途很顯然,看看其中一個的實現(xiàn)吧
            bool QVariant::canConvert(Type t) const
            {
                
            //we can treat floats as double
                
            //the reason for not doing it the "proper" way is that QMetaType::Float's value is 135,
                
            //which can't be handled by qCanConvertMatrix
                
            //In addition QVariant::Type doesn't have a Float value, so we're using QMetaType::Float
                const uint currentType = ((d.type == QMetaType::Float) ? QVariant::Double : d.type);
                
            if (uint(t) == uint(QMetaType::Float)) t = QVariant::Double;

                
            if (currentType == uint(t))
                    
            return true;

                
            if (currentType > QVariant::LastCoreType || t > QVariant::LastCoreType) {
                    
            switch (uint(t)) {
                    
            case QVariant::Int:
                        
            return currentType == QVariant::KeySequence
                               
            || currentType == QMetaType::ULong
                               
            || currentType == QMetaType::Long
                               
            || currentType == QMetaType::UShort
                               
            || currentType == QMetaType::UChar
                               
            || currentType == QMetaType::Char
                               
            || currentType == QMetaType::Short;
                    
            case QVariant::Image:
                        
            return currentType == QVariant::Pixmap || currentType == QVariant::Bitmap;
                    
            case QVariant::Pixmap:
                        
            return currentType == QVariant::Image || currentType == QVariant::Bitmap
                                          
            || currentType == QVariant::Brush;
                    
            case QVariant::Bitmap:
                        
            return currentType == QVariant::Pixmap || currentType == QVariant::Image;
                    
            case QVariant::ByteArray:
                        
            return currentType == QVariant::Color;
                    
            case QVariant::String:
                        
            return currentType == QVariant::KeySequence || currentType == QVariant::Font
                                          
            || currentType == QVariant::Color;
                    
            case QVariant::KeySequence:
                        
            return currentType == QVariant::String || currentType == QVariant::Int;
                    
            case QVariant::Font:
                        
            return currentType == QVariant::String;
                    
            case QVariant::Color:
                        
            return currentType == QVariant::String || currentType == QVariant::ByteArray
                                          
            || currentType == QVariant::Brush;
                    
            case QVariant::Brush:
                        
            return currentType == QVariant::Color || currentType == QVariant::Pixmap;
                    
            case QMetaType::Long:
                    
            case QMetaType::Char:
                    
            case QMetaType::UChar:
                    
            case QMetaType::ULong:
                    
            case QMetaType::Short:
                    
            case QMetaType::UShort:
                        
            return qCanConvertMatrix[QVariant::Int] & (1 << currentType) || currentType == QVariant::Int;
                    
            default:
                        
            return false;
                    }
                }

                
            if(t == String && currentType == StringList)
                    
            return v_cast<QStringList>(&d)->count() == 1;
                
            else
                    
            return qCanConvertMatrix[t] & (1 << currentType);
            }
            該函數(shù)作用是檢測存儲對象是否可以轉(zhuǎn)換為輸入類型,具體實現(xiàn)很明了
            4.QVariant對象的最后一個主要的功能就是到給定類型的轉(zhuǎn)換
            函數(shù)簇如下:
            int toInt(bool *ok = 0const;
                
            uint toUInt(bool *ok = 0const;
                qlonglong toLongLong(
            bool *ok = 0const;
                qulonglong toULongLong(
            bool *ok = 0const;
                
            bool toBool() const;
                
            double toDouble(bool *ok = 0const;
                
            float toFloat(bool *ok = 0const;
                qreal toReal(
            bool *ok = 0const;
                QByteArray toByteArray() 
            const;
                QBitArray toBitArray() 
            const;
                QString toString() 
            const;
                QStringList toStringList() 
            const;
                QChar toChar() 
            const;
                QDate toDate() 
            const;
                QTime toTime() 
            const;
                QDateTime toDateTime() 
            const;
                QList
            <QVariant> toList() const;
                QMap
            <QString, QVariant> toMap() const;
                QHash
            <QString, QVariant> toHash() const;
            其一個實現(xiàn)如下:
            /*!
                \fn QTime QVariant::toTime() const

                Returns the variant as a QTime if the variant has type() \l Time,
                \l DateTime, or \l String; otherwise returns an invalid time.

                If the type() is \l String, an invalid time will be returned if
                the string cannot be parsed as a Qt::ISODate format time.

                \sa canConvert(), convert()
            */
            QTime QVariant::toTime() 
            const
            {
                
            return qVariantToHelper<QTime>(d, Time, handler);
            }
            使用了模板函數(shù):qVariantToHelper
            5.關(guān)于qVariantToHelper
            /*!
                \fn bool QVariant::isValid() const

                Returns true if the storage type of this variant is not
                QVariant::Invalid; otherwise returns false.
            */

            template 
            <typename T>
            inline T qVariantToHelper(
            const QVariant::Private &d, QVariant::Type t,
                                      
            const QVariant::Handler *handler, T * = 0)
            {
                
            if (d.type == t)
                    
            return *v_cast<T>(&d);

                T ret;
                handler
            ->convert(&d, t, &ret, 0);
                
            return ret;
            }
            該函數(shù)根據(jù)對象信息和目標類型做轉(zhuǎn)換工作,如果二者類型一致,則直接做轉(zhuǎn)換,否則交給函數(shù)handler->convert處理
            6.關(guān)于Handler對象
                struct Handler {
                    f_construct construct;
                    f_clear clear;
                    f_null isNull;
            #ifndef QT_NO_DATASTREAM
                    f_load load;
                    f_save save;
            #endif
                    f_compare compare;
                    f_convert convert;
                    f_canConvert canConvert;
                    f_debugStream debugStream;
                };
            不過好像沒看出什么門道,那就繼續(xù)看看
            其實際結(jié)構(gòu)為:
            const QVariant::Handler qt_kernel_variant_handler = {
                construct,
                clear,
                isNull,
            #ifndef QT_NO_DATASTREAM
                
            0,
                
            0,
            #endif
                compare,
                convert,
                
            0,
            #if !defined(QT_NO_DEBUG_STREAM) && !defined(Q_BROKEN_DEBUG_STREAM)
                streamDebug
            #else
                
            0
            #endif
            };
            再看其中 一個函數(shù)實現(xiàn)constuct
            static void construct(QVariant::Private *x, const void *copy)
            {
                x
            ->is_shared = false;

                
            switch (x->type) {
                
            case QVariant::String:
                    v_construct
            <QString>(x, copy);
                    
            break;
                
            case QVariant::Char:
                    v_construct
            <QChar>(x, copy);
                    
            break;
                
            case QVariant::StringList:
                    v_construct
            <QStringList>(x, copy);
                    
            break;
                
            case QVariant::Map:
                    v_construct
            <QVariantMap>(x, copy);
                    
            break;
                
            case QVariant::Hash:
                    v_construct
            <QVariantHash>(x, copy);
                    
            break;
                
            case QVariant::List:
                    v_construct
            <QVariantList>(x, copy);
                    
            break;
                
            case QVariant::Date:
                    v_construct
            <QDate>(x, copy);
                    
            break;
                
            case QVariant::Time:
                    v_construct
            <QTime>(x, copy);
                    
            break;
                
            case QVariant::DateTime:
                    v_construct
            <QDateTime>(x, copy);
                    
            break;
                
            case QVariant::ByteArray:
                    v_construct
            <QByteArray>(x, copy);
                    
            break;
                
            case QVariant::BitArray:
                    v_construct
            <QBitArray>(x, copy);
                    
            break;
            #ifndef QT_NO_GEOM_VARIANT
                
            case QVariant::Size:
                    v_construct
            <QSize>(x, copy);
                    
            break;
                
            case QVariant::SizeF:
                    v_construct
            <QSizeF>(x, copy);
                    
            break;
                
            case QVariant::Rect:
                    v_construct
            <QRect>(x, copy);
                    
            break;
                
            case QVariant::LineF:
                    v_construct
            <QLineF>(x, copy);
                    
            break;
                
            case QVariant::Line:
                    v_construct
            <QLine>(x, copy);
                    
            break;
                
            case QVariant::RectF:
                    v_construct
            <QRectF>(x, copy);
                    
            break;
                
            case QVariant::Point:
                    v_construct
            <QPoint>(x, copy);
                    
            break;
                
            case QVariant::PointF:
                    v_construct
            <QPointF>(x, copy);
                    
            break;
            #endif
                
            case QVariant::Url:
                    v_construct
            <QUrl>(x, copy);
                    
            break;
                
            case QVariant::Locale:
                    v_construct
            <QLocale>(x, copy);
                    
            break;
            #ifndef QT_NO_REGEXP
                
            case QVariant::RegExp:
                    v_construct
            <QRegExp>(x, copy);
                    
            break;
            #endif
            #ifndef QT_BOOTSTRAPPED
                
            case QVariant::EasingCurve:
                    v_construct
            <QEasingCurve>(x, copy);
                    
            break;
            #endif
                
            case QVariant::Int:
                    x
            ->data.i = copy ? *static_cast<const int *>(copy) : 0;
                    
            break;
                
            case QVariant::UInt:
                    x
            ->data.u = copy ? *static_cast<const uint *>(copy) : 0u;
                    
            break;
                
            case QVariant::Bool:
                    x
            ->data.b = copy ? *static_cast<const bool *>(copy) : false;
                    
            break;
                
            case QVariant::Double:
                    x
            ->data.d = copy ? *static_cast<const double*>(copy) : 0.0;
                    
            break;
                
            case QMetaType::Float:
                    x
            ->data.f = copy ? *static_cast<const float*>(copy) : 0.0f;
                    
            break;
                
            case QMetaType::QObjectStar:
                    x
            ->data.o = copy ? *static_cast<QObject *const*>(copy) : 0;
                    
            break;
                
            case QVariant::LongLong:
                    x
            ->data.ll = copy ? *static_cast<const qlonglong *>(copy) : Q_INT64_C(0);
                    
            break;
                
            case QVariant::ULongLong:
                    x
            ->data.ull = copy ? *static_cast<const qulonglong *>(copy) : Q_UINT64_C(0);
                    
            break;
                
            case QVariant::Invalid:
                
            case QVariant::UserType:
                    
            break;
                
            default:
                    
            void *ptr = QMetaType::construct(x->type, copy);
                    
            if (!ptr) {
                        x
            ->type = QVariant::Invalid;
                    } 
            else {
                        x
            ->is_shared = true;
                        x
            ->data.shared = new QVariant::PrivateShared(ptr);
                    }
                    
            break;
                }
                x
            ->is_null = !copy;
            }
            繼續(xù)看v_construct
            該函數(shù)模板實現(xiàn)和平臺有關(guān),其中一個平臺的實現(xiàn)如下:
            template <class T>
            inline 
            void v_construct(QVariant::Private *x, const void *copy, T * = 0)
            {
                
            if (sizeof(T) > sizeof(QVariant::Private::Data)) {
                    x
            ->data.shared = copy ? new QVariantPrivateSharedEx<T>(*static_cast<const T *>(copy))
                                          : 
            new QVariantPrivateSharedEx<T>;
                    x
            ->is_shared = true;
                } 
            else {
                    
            if (copy)
                        
            new (&x->data.ptr) T(*static_cast<const T *>(copy));
                    
            else
                        
            new (&x->data.ptr) T;
                }
            }
            這里主要是把傳入對象指針導(dǎo)入為本身的數(shù)據(jù)指針data.ptr

            QVariant大致就這個樣子
            posted on 2011-12-10 20:51 ccsdu2009 閱讀(4351) 評論(0)  編輯 收藏 引用 所屬分類: QT源碼分析
             
            久久天天躁狠狠躁夜夜av浪潮| 精品久久久无码21p发布 | 久久久久久久波多野结衣高潮| 久久婷婷色综合一区二区| 91久久精品91久久性色| 久久久亚洲精品蜜桃臀| 国产精品无码久久久久久| 久久精品中文字幕有码| 成人妇女免费播放久久久 | 久久综合国产乱子伦精品免费| 久久免费精品一区二区| 国产A级毛片久久久精品毛片| 精品久久久久中文字| 久久久久99精品成人片直播| 四虎国产精品免费久久5151| 亚洲AV无一区二区三区久久 | 人妻无码αv中文字幕久久琪琪布 人妻无码精品久久亚瑟影视 | 国产精品久久午夜夜伦鲁鲁| 亚洲国产成人精品女人久久久 | 久久99精品久久久久久9蜜桃| 久久久久亚洲Av无码专| 最新久久免费视频| 久久综合九色欧美综合狠狠| 国产成人久久精品激情| 亚洲精品tv久久久久久久久| 亚洲人成无码久久电影网站| 久久影院午夜理论片无码| 久久精品成人影院| 草草久久久无码国产专区| 久久精品国产亚洲一区二区| 999久久久无码国产精品| 久久丫精品国产亚洲av| 欧美牲交A欧牲交aⅴ久久| 色欲综合久久中文字幕网| 亚洲精品乱码久久久久久 | 国产午夜福利精品久久2021| 精品熟女少妇av免费久久| 欧美喷潮久久久XXXXx| 无码人妻久久一区二区三区| 久久久久人妻一区二区三区vr| 久久亚洲中文字幕精品有坂深雪|