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

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            traits:Traits技術(shù)初探

            概述:
            traits
            是一種特性萃取技術(shù),它在Generic Programming中被廣泛運(yùn)用,常常被用于使不同的類型可以用于相同的操作,或者針對(duì)不同類型提供不同的實(shí)現(xiàn).traits在實(shí)現(xiàn)過程中往往需要用到以下三種C++的基本特性:
            enum
            typedef
            template
            (partial) specialization
            其中:
            enum
            用于將在不同類型間變化的標(biāo)示統(tǒng)一成一個(gè),它在C++中常常被用于在類中替代define,你可以稱enum為類中的define;
            typedef
            則用于定義你的模板類支持特性的形式,你的模板類必須以某種形式支持某一特性,否則類型萃取器traits將無法正常工作.看到這里你可能會(huì)想,太苛刻了吧?其實(shí)不然,不支持某種特性本身也是一種支持的方式(見示例2,我們定義了兩種標(biāo)示,__xtrue_type__xfalse_type,分別表示對(duì)某特性支持和不支持).
            template
            (partial) specialization被用于提供針對(duì)特定類型的正確的或更合適的版本.
            借助以上幾種簡單技術(shù),我們可以利用traits提取類中定義的特性,并根據(jù)不同的特性提供不同的實(shí)現(xiàn).你可以將從特性的定義到萃取,再到traits的實(shí)際使用統(tǒng)稱為traits技術(shù),但這種定義使得traits顯得過于復(fù)雜,我更愿意將traits的定義限于特性萃取,因?yàn)檫@種定義使得traits顯得更簡單,更易于理解,^_^.

            舉例:
            上面提到過,traits可被用于針對(duì)不同類型提供不同的實(shí)現(xiàn),那么下面就舉兩個(gè)例子來說明如何實(shí)現(xiàn)這一點(diǎn).
            Example 1:
            假定我們需要為某個(gè)類設(shè)計(jì)一個(gè)可以對(duì)所有類型(包括普通的int/long...,提供了clone方法的復(fù)雜類型CComplexObject,及由該類派生的類)進(jìn)行操作的函數(shù)clone,下面,先用OO的方法來考慮一下解決方案.看到前面的條件,最先跳進(jìn)你腦子里的肯定是Interface,pure virtual function等等.對(duì)于我們自己設(shè)計(jì)的類CComplexObject而言,這不是問題,但是,對(duì)于基本數(shù)據(jù)類型呢?還有那些沒有提供clone方法的復(fù)雜類型呢?(這時(shí)候你可能會(huì)想,要是Java該多easy,所有類都默認(rèn)從Object派生,Object已提供了一個(gè)默認(rèn)的clone方法,但是,要使類真正支持clone,還必須implements Cloneable,所以,同樣也不能避免這里遇到的麻煩).
            下面是一個(gè)可能的解決方案:
            template
            <typename T, bool isClonable>
            class
            XContainer
            {
                 ...

                 void
            clone(T* pObj)
                 {

                     if
            (isClonable)
                     {

                         pObj->clone();
                     }

                     else

                     {

                         //... non-Clonable algorithm ...
                     }
                 }
            };

            但是只要你測(cè)試一下,這段代碼不能通過編譯.為什么會(huì)這樣呢?原因很簡單:對(duì)于沒有實(shí)現(xiàn)clone方法的非Clonable類或基本類型,pObj->clone這一句是非法的.
            那么怎樣解決上面的這個(gè)難題呢?上面不能通過編譯的代碼告訴我們,要使我們的代碼通過編譯,就不能使非Clonable類或基本類型的代碼中出現(xiàn)pObj->clone,即我們需要針對(duì)不同類型提供不同的實(shí)現(xiàn).為了實(shí)現(xiàn)這一點(diǎn),我們可以在我們的模板類中用enum定義一個(gè)trait,以標(biāo)示類是否為Clonable,然后在原模板類內(nèi)部引入一個(gè)traits提取類Traits,通過對(duì)該類進(jìn)行specilizing,以根據(jù)不同的trait提供不同的實(shí)現(xiàn).具體實(shí)現(xiàn)如下:
            #include <iostream>
            using namespace std;

            class
            CComplexObject // a demo class
            {
            public
            :
                 void
            clone() { cout << "in clone" << endl; }
            };


            // Solving the problem of choosing method to call by inner traits class
            template <typename T, bool isClonable>
            class
            XContainer
            {

            public
            :
                 enum
            {Clonable = isClonable};

                 void
            clone(T* pObj)
                 {

                     Traits<isClonable>().clone(pObj);
                 }


                 template
            <bool flag>
                     class
            Traits
                 {
                 };


                 template
            <>
                     class
            Traits<true>
                 {

                 public
            :
                     void
            clone(T* pObj)
                     {

                         cout << "before cloning Clonable type" << endl;
                         pObj->clone();
                         cout << "after cloning Clonable type" << endl;
                     }
                 };


                 template
            <>
                     class
            Traits<false>
                 {

                 public
            :
                     void
            clone(T* pObj)
                     {

                         cout << "cloning non Clonable type" << endl;
                     }
                 };
            };


            void
            main()
            {

                 int
            * p1 = 0;
                 CComplexObject* p2 = 0;

                 XContainer<int, false> n1;
                 XContainer<CComplexObject, true> n2;

                 n1.clone(p1);
                 n2.clone(p2);
            }

            編譯運(yùn)行一下,上面的程序輸出如下的結(jié)果:
            doing something non Clonable
            before doing something Clonable
            in clone
            after doing something Clonable
            這說明,我們成功地根據(jù)傳入的isClonable模板參數(shù)為模板實(shí)例選擇了不同的操作,在保證接口相同的情況下,為不同類型提供了不同的實(shí)現(xiàn).

            Example 2:
            我們?cè)賹?duì)上面的例子進(jìn)行一些限制,假設(shè)我們的clone操作只涉及基本類型和CComplexObject及其派生類,那么我們可以進(jìn)一步給出下面的解法:
            #include <iostream>
            using namespace std;

            struct
            __xtrue_type { }; // define two mark-type
            struct __xfalse_type { };

            class
            CComplexObject // a demo class
            {
            public
            :
                 virtual
            void clone() { cout << "in clone" << endl; }
            };


            class
            CDerivedComplexObject : public CComplexObject // a demo derived class
            {
            public
            :
                 virtual
            void clone() { cout << "in derived clone" << endl; }
            };


            // A general edtion of Traits
            template <typename T>
            struct
            Traits
            {

                 typedef
            __xfalse_type has_clone_method; // trait 1: has clone method or not? All types defaultly has no clone method.
            };

            // Specialized edtion for ComplexObject
            template <>
            struct
            Traits<CComplexObject>
            {

                 typedef
            __xtrue_type has_clone_method;
            };


            template
            <typename T>
            class
            XContainer
            {

                 template
            <typename flag>
                     class
            Impl
                 {
                 };

                 template
            <>
                     class
            Impl <__xtrue_type>
                 {

                 public
            :
                     void
            clone(T* pObj)
                     {

                         pObj->clone();
                     }
                 };

                 template
            <>
                     class
            Impl <__xfalse_type>
                 {

                 public
            :
                     void
            clone(T* pObj)
                     {
                     }
                 };

            public
            :
                 void
            clone(T* pObj)
                 {

                     Impl<Traits<T>::has_clone_method>().clone(pObj);
                 }
            };


            void
            main()
            {

                 int
            * p1 = 0;
                 CComplexObject c2;
                 CComplexObject* p2 = &c2;
                 CDerivedComplexObject c3;
                 CComplexObject* p3 = &c3; // you must point to a derived object by a base-class pointer,
                                         //it's a little problem

                 XContainer<int> n1;
                 XContainer<CComplexObject> n2;
                 XContainer<CComplexObject> n3;

                 n1.clone(p1);
                 n2.clone(p2);
                 n3.clone(p3);
            }

            現(xiàn)在,所有基本類型以及CComplexObject類系都可以用于XContainer.

            結(jié)語:
            看到這里,你或許會(huì)說,traits不過如此,還以為是什么高深的玩意呢!其實(shí)技術(shù)就是這樣,說白了都很Easy,關(guān)鍵是怎么將他們用于實(shí)際,為實(shí)際的Designing/Development服務(wù).畢竟,IT領(lǐng)域,不能應(yīng)用于實(shí)際的技術(shù)是沒有價(jià)值的.

            posted on 2008-11-09 01:19 肥仔 閱讀(7908) 評(píng)論(1)  編輯 收藏 引用 所屬分類: C++ 模板

            評(píng)論

            # re: traits:Traits技術(shù)初探  回復(fù)  更多評(píng)論   

            示例不能運(yùn)行啊
            2016-04-26 11:31 | lzq
            久久久久久久久久免免费精品| segui久久国产精品| 久久精品国产免费观看| 久久婷婷五月综合色奶水99啪| 天天躁日日躁狠狠久久| 免费观看久久精彩视频| 中文成人无码精品久久久不卡| 精品永久久福利一区二区| 久久播电影网| 亚洲午夜久久久精品影院| 国产高清国内精品福利99久久| 欧美精品丝袜久久久中文字幕 | 亚洲精品无码成人片久久| 99久久99久久| 久久久久久精品免费免费自慰 | 久久人人青草97香蕉| 97久久超碰成人精品网站| 四虎国产精品成人免费久久| 久久亚洲欧美国产精品| 一本大道久久东京热无码AV| 狠狠狠色丁香婷婷综合久久五月 | 日产精品久久久久久久| 国产精品成人无码久久久久久| 日韩精品久久无码中文字幕| 久久国产热这里只有精品| 狠狠色丁香久久婷婷综合五月| 久久99国产精品久久99小说| 精品久久久久国产免费| 欧美激情精品久久久久| 久久久久久久97| 久久亚洲AV成人出白浆无码国产| 亚洲国产精品狼友中文久久久| 国产成人久久精品二区三区| 久久精品人人做人人爽电影| 久久偷看各类wc女厕嘘嘘| 久久无码高潮喷水| 噜噜噜色噜噜噜久久| 久久人人爽人爽人人爽av| 免费一级欧美大片久久网 | 99久久国产综合精品五月天喷水 | 久久久精品波多野结衣|