一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

QT 動(dòng)態(tài)創(chuàng)建對(duì)象

 guitarhua 2016-09-09

原文:http://www./node/350

在我繼續(xù)一系列的Qt數(shù)據(jù)序列化文章之前,有一個(gè)相對(duì)重要的需要提及的話題,那就是:基于類名動(dòng)態(tài)創(chuàng)建類對(duì)象的能力。

        假定現(xiàn)在我們要?jiǎng)?chuàng)建一系列的形狀,形狀是一個(gè)抽象類,實(shí)際類是存儲(chǔ)在一個(gè)列表中的各種各樣的派生類:矩形、圓等等。在序列化期間,我們可以保存每一項(xiàng)的類 名和對(duì)象數(shù)據(jù),在反序列化(即加載數(shù)據(jù))時(shí),我們需要能夠創(chuàng)建合適類實(shí)例的能力,這就是要用到一個(gè)對(duì)象工廠的地方。在支持反射的語言中,例如C#、 Java,僅需要幾行代碼就可以從一個(gè)跟定的類名字符串獲得一個(gè)類實(shí)例。但是在c++中沒有這樣的機(jī)制。

       一個(gè)簡單的解決方案是創(chuàng)建一個(gè)單獨(dú)的函數(shù),里面有一個(gè)大的switch塊(或者一系列的switch塊)來創(chuàng)建合適的類對(duì)象,盡管這種方法不雅觀并且破 壞了面向?qū)ο笤O(shè)計(jì),但是大多數(shù)情況下是可以接受的。然而,當(dāng)你有很多的類而且分散在應(yīng)用程序的不同模塊時(shí),使用上述方法可能會(huì)變得難以管理,而且當(dāng)應(yīng)用程 序有擴(kuò)展的模塊和動(dòng)態(tài)加載的插件時(shí),這就會(huì)變得更加困難。

      另一個(gè)更優(yōu)雅的解決方法是有一個(gè)不需要知道任何對(duì)象類型的工廠,而要通過工廠實(shí)例化的類必須使用某種內(nèi)部圖來先注冊(cè),這樣,每個(gè)模塊或插件可以獨(dú)立的注冊(cè)它們各自類。

       QT有兩種可以用來創(chuàng)建這樣的工廠的機(jī)制,它們看起來相似,實(shí)際上有很大的差別:

       QMetaType

       construct()方法能夠用來創(chuàng)建任何內(nèi)建類型的實(shí)例,或者是通過Q_DECLARE_METATYPE宏指定的自定義類型。這是 QVariant所要做的,用來內(nèi)部封裝自定義類型。然而這種機(jī)制是用來供變量類型使用的,也就是有默認(rèn)構(gòu)造和拷貝函數(shù)的類,但是對(duì)于抽象類對(duì)象是沒有意 義的,因?yàn)槌橄箢愅ǔJ褂弥羔槀鬟f,并且拷貝構(gòu)造通常被禁用。

       QMetaObject

       newInstance()方法可以用來創(chuàng)建任何一個(gè)從QObject派生下來的類的實(shí)例,僅有的條件是類的構(gòu)造器必須通過Q_INVOKABLE修 飾,來明確地聲明。這和多態(tài)對(duì)象配合可以很好的工作,因?yàn)镼Object類通常作為各種抽象類的基類。值得注意的是,從QT4開始,若沒有額外的工作,僅 僅依靠類名是不可能檢索到QMetaObject的。


       可以很容易的創(chuàng)建一個(gè)依賴于QMetaObject的對(duì)象工廠,這里有一種實(shí)現(xiàn),不過這種解決方法也有一些缺點(diǎn):
       構(gòu)造器必須使用Q_InVOKABLE顯示聲明,以便能夠訪問QMetaObject;

       沒有在編譯期檢查是否存在合適的構(gòu)造函數(shù)可以訪問,或者參數(shù)類型是否正確,當(dāng)你實(shí)際嘗試創(chuàng)建實(shí)例時(shí),僅僅會(huì)得到一個(gè)運(yùn)行時(shí)警告,并返回空指針;

      子類化QObject會(huì)增加每個(gè)對(duì)象實(shí)例的內(nèi)存占用,當(dāng)執(zhí)行運(yùn)行時(shí)類型檢查時(shí),通過QMetaObject進(jìn)行的動(dòng)態(tài)方法調(diào)用也會(huì)存在一些開銷。


      然而,創(chuàng)建一個(gè)可以創(chuàng)建任何類的自定義類工廠也不是難事,下面是一個(gè)適用于任何繼承于QObject的類的創(chuàng)建工廠:

class ObjectFactory
{
public:
    template<typename T>
    static void registerClass()
    {
        constructors().insert( T::staticMetaObject.className(), &constructorHelper<T> );
    }

    static QObject* createObject( const QByteArray& className, QObject* parent = NULL )
    {
        Constructor constructor = constructors().value( className );
        if ( constructor == NULL )
            return NULL;
        return (*constructor)( parent );
    }

private:
    typedef QObject* (*Constructor)( QObject* parent );

    template<typename T>
    static QObject* constructorHelper( QObject* parent )
    {
        return new T( parent );
    }

    static QHash<QByteArray, Constructor>& constructors()
    {
        static QHash<QByteArray, Constructor> instance;
        return instance;
    }
}; 

       使用這種途徑,不在需要使用Q_INVOKABLE聲明構(gòu)造器了,而且如果沒有找到合適的構(gòu)造器,只要這個(gè)類注冊(cè)了,在constructorHelper()方法中就會(huì)報(bào)告一個(gè)編譯錯(cuò)誤。而且代碼很容易使用:

ObjectFactory::registerClass<Foo>();

// ...

QObject* foo = ObjectFactory::createObject( "Foo" );

      同時(shí)也很容易修改這個(gè)代碼,來適用于那些不從QObject繼承的自定義抽象類,例如它可以使用任何傳遞給registerClass()方法或者自動(dòng)從 類的靜態(tài)成員接收的類型的“Key”,而不是使用從OMetaObject接收的類名作為“Key”.根據(jù)需要還有一組不同的參數(shù)可以傳遞給構(gòu)造函數(shù)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    超碰在线免费公开中国黄片| 色婷婷亚洲精品综合网| 日韩成人高清免费在线| 久久精品久久久精品久久| 日韩av欧美中文字幕| 中文字幕免费观看亚洲视频| 91欧美一区二区三区| 国产自拍欧美日韩在线观看| 一区二区在线激情视频| 国产精品欧美一区二区三区不卡| 少妇人妻精品一区二区三区| 国产成人精品一区在线观看| 欧美做爰猛烈叫床大尺度| 人妻一区二区三区多毛女| 99视频精品免费视频| 国产91色综合久久高清| 国产免费无遮挡精品视频 | 日韩欧美一区二区久久婷婷| 欧美小黄片在线一级观看| 色婷婷日本视频在线观看| 日本人妻免费一区二区三区| 国产成人免费激情视频| 色丁香一区二区黑人巨大| 91欧美视频在线观看免费| 99久久精品久久免费| 亚洲男人的天堂色偷偷| 又色又爽又黄的三级视频| 国产乱久久亚洲国产精品| 人妻露脸一区二区三区| 日韩女优视频国产一区| 午夜福利视频日本一区| 国产原创中文av在线播放| 亚洲国产精品久久琪琪| 在线观看免费午夜福利| 欧美一区二区在线日韩| 少妇熟女亚洲色图av天堂| 国产成人精品一区二三区在线观看| 亚洲精品欧美精品日韩精品| 日韩精品中文字幕亚洲| 精品欧美日韩一区二区三区 | 观看日韩精品在线视频|