• <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>

            歲月流轉(zhuǎn),往昔空明

            C++博客 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
              118 Posts :: 3 Stories :: 413 Comments :: 0 Trackbacks
            創(chuàng)建型模式的使用
            GOF94的創(chuàng)建型模式,總共有五種。其中一種的范圍是類(lèi)的,四種是對(duì)象的。
            1.Factory Method(virtual constructor)。
            工廠方法在創(chuàng)建型模式里面的使用的頻率是很高的,也是非常容易使用的。
            由于工廠方法本身的一些特點(diǎn),它們往往被說(shuō)明成為靜態(tài)的,如果這個(gè)靜態(tài)函數(shù)就是待創(chuàng)建的類(lèi)型的靜態(tài)成員函數(shù),那么,這就是Meyer所謂的 virtual constructor。(More Effective C++)這個(gè)東東很是厲害,我們可以利用它,依據(jù)數(shù)據(jù)創(chuàng)建正確的對(duì)象。
            在游戲的過(guò)程中,存檔和取檔是在所難免的。在存儲(chǔ)的過(guò)程中,你需要將一個(gè)自定義類(lèi)串行化到文件中。這個(gè)到不是什么難事。但是如果你要從文件中讀取對(duì)象呢? 首先你就需要知道這個(gè)對(duì)象的類(lèi),然后才能創(chuàng)建啊。這個(gè)時(shí)候,virtual constructor便可以顯示出它的作用來(lái)。什么?你知道了?好,你寫(xiě)一 段代碼給我看看。

            TypeID id;//類(lèi)標(biāo)識(shí),每個(gè)類(lèi)唯一,可以籍此判斷類(lèi)型
            switch (id)
            {
            case NPC_ID : 
            //創(chuàng)建NPC,讀入數(shù)據(jù)。。。
            case MONSTOR: 

            }

            不不不,我絕對(duì)不是叫你要這么寫(xiě)!這段代碼的代價(jià)太大了。有效率的做法是,我們使用一個(gè)映射表。方法不是靜態(tài)的嗎?那好,我就給它統(tǒng)一一個(gè)函數(shù)聲明:
            typedef (void*)(*PFnCreateObject)(ByteStream& stream/*資源流*/);
            注意,這后面的這個(gè)void*理論上是需要返回一個(gè)指針,而這個(gè)指針又因?yàn)轭?lèi)型轉(zhuǎn)換而失去了識(shí)別類(lèi)型的作用。但是不要忘了,我們調(diào)用的是一個(gè)函數(shù),一切需要彌補(bǔ)的缺陷,都可以在函數(shù)中完成。
            因此,我們可以這樣寫(xiě)一個(gè)查找表:
            PFnCreateObject creatorFuncTable[MAX_TYPE_ID];
            在程序需要讀取存檔的時(shí)候,我們可以:
            void Load(ByteStream& stream)
            {
              
            //
              TypeID id;
              stream.Read(
            &id);
              (
            *creatorFuncTable[id])(stream);
              
            //
            }
            這種做法的麻煩之處在于要為每一個(gè)類(lèi)開(kāi)一個(gè)ID。如果是手工完成這一項(xiàng)的話,是很需要點(diǎn)功夫的。而且維護(hù)起來(lái)也不是很方便。因此,這里可以用GUID再HASH的辦法獲取一個(gè)Hash表。保存對(duì)象時(shí)要保存相應(yīng)的GUID,查找時(shí)使用Hash查找。
            順便說(shuō)一下,如果有個(gè)非虛函數(shù) Foo,有個(gè)類(lèi)
            class A
            {
              
            void foo() {
                
            if(this == NULL) {
                  
            //操作,但是不能調(diào)用A類(lèi)的非靜態(tài)成員或虛函數(shù)
                  cout << "Aha! 還是能運(yùn)行哦!" << endl;
                } 
            else {
                  cout 
            << "沒(méi)什么了不起的,地球人都知道!" << endl;
                }
              }
            };
            //
            A* p = NULL;
            p
            ->foo(); 

             這個(gè)調(diào)用是正確的!因?yàn)槌耸褂肊CX傳入NULL(this)以外,并沒(méi)有非法的內(nèi)存操作。因此,運(yùn)行時(shí)也不會(huì)有錯(cuò)誤。 當(dāng)然,以上的調(diào)用實(shí)際上是不可取的。而且當(dāng)foo為虛函數(shù)的時(shí)候,這種調(diào)用就不能正確進(jìn)行了,因?yàn)樘摵瘮?shù)是先要訪問(wèn)虛函數(shù)表的,而虛函數(shù)表又是對(duì)象而不是類(lèi)的一部分,調(diào)用了就訪問(wèn)了錯(cuò)誤的地址,所以其行為是不確定的。
            所以說(shuō),F(xiàn)actory Method 的特點(diǎn)就是:依據(jù)不同條件,創(chuàng)造不同型別。(這里的條件就是煩人的類(lèi)型ID)在創(chuàng)建之前,我們不能確定物體的型別。
            如果我們將靜態(tài)函數(shù)變?yōu)橐粋€(gè)類(lèi)(不是被創(chuàng)建的類(lèi))的成員函數(shù),那么,這個(gè)結(jié)構(gòu)就和Gof94上的描述一樣了。Gof94上的 Factory Method,有著它自己的特點(diǎn),這一點(diǎn)請(qǐng)參見(jiàn)書(shū)本。這里與Gof94的帶繼承的工廠方法相比,只是說(shuō)對(duì)于不同的創(chuàng)建條件,構(gòu)造函數(shù)的分 派方式不同而已。(這點(diǎn)我將在下面講述到)
            通過(guò)對(duì)工廠方法的使用,我們可以實(shí)現(xiàn)很多的功能,例如利用池分配等等。其中的一些功能,我們也可以通過(guò)重載operator new和 operator delete的辦法實(shí)現(xiàn),但是一些其它的功能,這種方法實(shí)現(xiàn)起來(lái)就會(huì)很吃力或者不可行,那么,工廠方法就為我們?cè)趧?chuàng)建的時(shí)候便搭建了一 個(gè)足夠我們恣意施展才華的場(chǎng)所。
            posted on 2007-06-07 17:45 空明流轉(zhuǎn) 閱讀(979) 評(píng)論(3)  編輯 收藏 引用

            評(píng)論

            # re: 亂彈游戲中的設(shè)計(jì)模式 - Factory Method 2007-06-07 21:46 李錦俊
            I Like 設(shè)計(jì)模式~~
            多寫(xiě)寫(xiě)類(lèi)似的文章哦。
            我還有好多個(gè)設(shè)計(jì)模式還沒(méi)有理解啊。  回復(fù)  更多評(píng)論
              

            # re: 亂彈游戲中的設(shè)計(jì)模式 - Factory Method 2007-06-07 22:19 pass86
            估計(jì)PFnCreateObject creatorFuncTable[MAX_TYPE_ID];因該是
            PFnCreateObject* creatorFuncTable[MAX_TYPE_ID];  回復(fù)  更多評(píng)論
              

            # re: 亂彈游戲中的設(shè)計(jì)模式 - Factory Method 2007-06-07 23:25 空明流轉(zhuǎn)
            沒(méi)有錯(cuò),呵呵.  回復(fù)  更多評(píng)論
              


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久se这里只有精品| 日本WV一本一道久久香蕉| 久久本道久久综合伊人| 日韩美女18网站久久精品| 国产精品久久新婚兰兰 | 久久久午夜精品福利内容| 久久精品国产久精国产果冻传媒| 国内精品久久久久影院一蜜桃| 久久亚洲国产精品123区| 久久香综合精品久久伊人| 久久精品亚洲男人的天堂| 97久久久久人妻精品专区| 2020久久精品亚洲热综合一本| 久久国产成人精品麻豆| 国产毛片欧美毛片久久久| 精品综合久久久久久88小说| 亚洲香蕉网久久综合影视 | 亚洲美日韩Av中文字幕无码久久久妻妇| 日产精品久久久一区二区| 亚洲国产成人精品女人久久久| 成人亚洲欧美久久久久| 国产精品久久久久jk制服| 久久久久se色偷偷亚洲精品av| 久久久WWW成人免费精品| 亚洲成色999久久网站| 精品国产乱码久久久久久1区2区 | 国产成人综合久久精品尤物| 99999久久久久久亚洲| 亚洲熟妇无码另类久久久| 四虎影视久久久免费| 精品99久久aaa一级毛片| 88久久精品无码一区二区毛片| 精品久久久久久成人AV| 久久久久亚洲AV无码网站| 欧美大香线蕉线伊人久久| 99蜜桃臀久久久欧美精品网站| 人人妻久久人人澡人人爽人人精品| 久久综合久久性久99毛片| 亚洲午夜无码久久久久小说| 久久99国产精品久久99小说| 久久福利资源国产精品999|