• <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是一種可以存儲不同類型的數據結構,在很多場合這是很有用得
            為了達到這種目的,可以想象,該對象應該存儲對象的類型信息,數據信息以及其他輔助詳細
            考慮用途,這種對象必須支持對不同對象的存儲,對存儲類型的檢測以及取對象三個功能
            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負責記錄對象的類型,這對于正確取出對象是很用得
            3.成員函數
              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
            這幾個函數的用途很顯然,看看其中一個的實現吧
            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);
            }
            該函數作用是檢測存儲對象是否可以轉換為輸入類型,具體實現很明了
            4.QVariant對象的最后一個主要的功能就是到給定類型的轉換
            函數簇如下:
            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;
            其一個實現如下:
            /*!
                \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);
            }
            使用了模板函數:qVariantToHelper
            5.關于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;
            }
            該函數根據對象信息和目標類型做轉換工作,如果二者類型一致,則直接做轉換,否則交給函數handler->convert處理
            6.關于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;
                };
            不過好像沒看出什么門道,那就繼續看看
            其實際結構為:
            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
            };
            再看其中 一個函數實現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;
            }
            繼續看v_construct
            該函數模板實現和平臺有關,其中一個平臺的實現如下:
            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;
                }
            }
            這里主要是把傳入對象指針導入為本身的數據指針data.ptr

            QVariant大致就這個樣子
            posted on 2011-12-10 20:51 ccsdu2009 閱讀(4351) 評論(0)  編輯 收藏 引用 所屬分類: QT源碼分析
             
            久久亚洲国产成人影院| 亚洲AV无码1区2区久久| 亚洲综合久久综合激情久久| 精品国际久久久久999波多野| 国产精品毛片久久久久久久 | 无码人妻久久一区二区三区| 浪潮AV色综合久久天堂| 久久久久国产日韩精品网站| 亚洲国产精品一区二区久久hs| 97久久国产亚洲精品超碰热 | 久久只有这精品99| 日产精品久久久一区二区| 久久精品国产黑森林| 亚洲∧v久久久无码精品| 99热成人精品免费久久| 欧洲成人午夜精品无码区久久| 久久久久久久综合综合狠狠| 国产午夜精品久久久久免费视| 蜜桃麻豆www久久国产精品| 欧美综合天天夜夜久久| 亚洲精品乱码久久久久久蜜桃不卡 | 久久久国产视频| 国产精品99久久久久久宅男| 久久久精品国产sm调教网站| 中文字幕精品久久| 久久婷婷五月综合97色直播| 韩国三级大全久久网站| 久久精品国产亚洲精品2020| 国产美女亚洲精品久久久综合| 久久久久免费视频| 久久99国产精品成人欧美| 久久91亚洲人成电影网站| 精品999久久久久久中文字幕| 久久综合狠狠综合久久综合88| 无码国内精品久久综合88| 一本一本久久a久久精品综合麻豆| 久久av免费天堂小草播放| 久久精品18| 少妇久久久久久被弄到高潮| 一极黄色视频久久网站| 久久久亚洲AV波多野结衣|