<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      近幾天看《ATL INTERNALS》,看到了附錄中的一個關(guān)于template的小技巧-仿真動態(tài)綁定:

      template
      class Array {
      public:
      ……
      virtual int Compare(const Array& rhs) =0;

      bool operator< (const Array& rhs)
      { return this->Compare(rhs) < 0; }

      bool operator> (const Array& rhs)
      { return this->Compare(rhs) >0; }

      bool operator== (const Array& rhs)
      { return this->Compare(rhs) == 0; }

      T m_rg[1024];
      };

      然后派生類重寫這個虛函數(shù)獲得多態(tài)特性:

      class String : public Array {
      public:
      int Compare(const Array& rhs)
      { return strcmp(m_rg, rhs.m_rg); }
      };

      為了實現(xiàn)虛函數(shù)需要一個vptr和一個vtable,以及需要至少經(jīng)過兩次提領(lǐng)操作才能調(diào)用正確的函數(shù)。

      然后書中介紹了一種提供效率的辦法:

      template <typename T, typename Deriving>
      class Array {
      public:
      ……
      bool operator< (const Array& rhs)
      { return static_cast(this)->Compare(rhs) < 0; }

      bool operator> (const Array& rhs)
      { return static_cast(this)->Compare(rhs) > 0; }

      bool operator== (const Array& rhs)
      { return static_cast(this)->Compare(rhs) == 0; }

      T m_rg[1024];
      };

      注意Array模板接受一個附加的參數(shù)——派生類的名字。它利用這個類名完成堆自己的靜態(tài)強制轉(zhuǎn)換。因為編譯器會在實例化(具象化)派生類的同時展開基類的代碼,所以靜態(tài)強制轉(zhuǎn)換完成了一個完全安全的向下轉(zhuǎn)換。

      class String : public Array<char, String> {
      public:
      int Compare(const Array& rhs)
      { return strcmp(m_rg, rhs.m_rg); }
      };

      這項技術(shù)在不使用虛成員的情況下使得我們看到并且感受到了動態(tài)綁定。真的有 那么神奇嗎?虛函數(shù)真的可用通過模板來模擬?當(dāng)然不是

      一開始的時候我還覺得迷惑,但是隱約覺得這個東西只是看上去像虛函數(shù),但是限制多多。于是上網(wǎng)去問高手。gigix一開始被我說暈了,也怪我表述不好。問babysloth,一列出代碼他就知道了這個是什么了。他說: “這叫curiously recurring template pattern,由bell-lab的james coplien首先記錄下來”

      緊接著,我偶然看到以前下載的ATL相關(guān)技術(shù)解析的文章,里面詳細(xì)說了這個東西。文章是Codeguru上的《ATL Under the Hood Part 3》。簡短的一個程序說明了這個東西:

      #include
      using namespace std;

      class Base {
      public:
        virtual void fun() {
          cout << "Base::fun" << endl;
        }

        void doSomething() {
          fun();
        }
      };

      class Drive : public Base {
      public:
        void fun() {
          cout << "Drive::fun" << endl;
        }
      };

      int main() {
        Drive obj;
        obj.doSomething();

        return 0;
      }

      這段程序中的行為和下面的這段程序是一樣的:

      #include
      using namespace std;

      template
      class Base {
      public:
        void fun() {
          cout << "Base::fun" << endl;
        }

        void doSomething() {
          T* pT = static_cast(this);
          pT->fun();
        }
      };

      class Drive : public Base {
      public:
        void fun() {
          cout << "Drive::fun" << endl;
        }
      };

      int main() {
        Drive obj;
        obj.doSomething();

        return 0;
      }

      這里說的結(jié)果是一樣的。引用蟲蟲的一句話:“效率不同”。

      問題就是這里只是表現(xiàn)了虛函數(shù)的一個部分,虛函數(shù)一個經(jīng)典的例子是用數(shù)組來保存派生類指針,通過指針調(diào)用被改寫了的虛函數(shù)來表現(xiàn)多態(tài)。用這個模擬的版本可以這么作嗎?不行!

      下面這么作是不行的:

      #include
      using namespace std;

      template
      class Base {
      public:
        void fun() {
          cout << "Base::fun" << endl;
        }

        void doSomething() {
          T* pT = static_cast(this);
          pT->fun();
        }
      };

      class Drive1 : public Base {
      public:
        void fun() {
          cout << "Drive1::fun" << endl;
        }
      };

      class Drive2 : public Base {
      public:
        void fun() {
          cout << "Drive2::fun" << endl;
        }
      };

      int main() {
        Base* pBase = NULL;
        pBase = new Drive1;
        pBase->doSomething();
        delete pBase;

        pBase = new Drive2;
        pBase->doSomething();

        return 0;
      }

      因為Drive2與Drive1不匹配。另外這么模擬虛函數(shù)只能維持一層,不能像真正的虛函數(shù)一樣在派生的層次中任意的往下,虛函數(shù)一直都是虛函數(shù)。例如:

      #include
      using namespace std;

      template
      class Base {
      public:
        void fun() {
          cout << "Base::fun" << endl;
        }

        void doSomething() {
          T* pT = static_cast(this);
          pT->fun();
        }
      };

      class Drive : public Base {
      public:
        void fun() {
          cout << "Drive::fun" << endl;
        }
      };

      class MostDrive : public Drive {
      public:
        void fun() {
          cout << "MostDrive::fun" << endl;
        }
      };

      int main() {
        MostDrive obj;
        obj.doSomething();

        return 0;
      }

      輸出是Drive::fun而不是MostDrive::fun

      結(jié)論
      結(jié)論就是這里并不是什么模擬虛函數(shù),只是在這個情景下很像虛函數(shù),虛函數(shù)的幾個重要的性質(zhì)并沒有支持。這個只不過是一個程序設(shè)計中的idiom,關(guān)于模板的諸多技巧中的一個。

      主要用途:父類需要子類信息的時候。在父類中的一個函數(shù)a中需要調(diào)用子類中的某個函數(shù)b,以實現(xiàn)子類定制某些行為。

      主要原理:通過對this的強制類型轉(zhuǎn)換實現(xiàn)對pT->fun()的不同解釋。這種解釋是在編譯期間的。編譯期間展開模板的類型參數(shù),根據(jù)參數(shù)確定了this的轉(zhuǎn)換到的類型,從而也確定了pT->fun()的解釋。所以模擬的是靜態(tài)的多態(tài)性。

      使用方法:使用的方法不是像虛函數(shù)一樣通過對象的指針調(diào)用虛函數(shù)實現(xiàn)多態(tài)。而是通過調(diào)用從基類繼承來的某個普通函數(shù),在該函數(shù)中再去調(diào)用調(diào)用“經(jīng)過改寫”的派生類的函數(shù)。

      主要缺陷:就是虛擬性質(zhì)不具有傳遞性,不具有動態(tài)的多態(tài)性。所謂的多態(tài)也只不過是通過你傳遞的模板參數(shù)所隱含的意思決定具體的函數(shù)調(diào)用。

      感想:按照babysloth說法,這個也是一個設(shè)計模式。加上前段時間看《STL源碼剖析》感受的iterator等模式,覺得設(shè)計模式真是博大精深。等期中考試搞定了數(shù)學(xué)分析之后一定要向gigix借幾本這方面的書看看。
      posted on 2004-05-25 19:59  taowen  閱讀(1072)  評論(0)    收藏  舉報
      主站蜘蛛池模板: a4yy私人毛片| 无码一区二区三区视频| 亚洲愉拍一区二区三区| 国产中文字幕精品喷潮| 国产三级精品福利久久| 国产69精品久久久久99尤物| 亚洲国产成人不卡高清麻豆 | 精品在免费线中文字幕久久| 国产一区二区不卡在线视频| 欧美成人精品手机在线| 日韩内射美女人妻一区二区三区| 好深好湿好硬顶到了好爽| 久久天天躁狠狠躁夜夜躁| 久久久久成人片免费观看蜜芽| 麻豆人人妻人人妻人人片av| 国产成人亚洲综合图区| 婷婷六月色| 日韩高清亚洲日韩精品一区二区| 亚洲欧洲日产国码久在线| 日日碰狠狠添天天爽五月婷| 久久精品午夜视频| 免费午夜无码片在线观看影院| 亚洲人成电影在线播放| 国产极品精品自在线不卡| 深夜福利成人免费在线观看| 久久精品亚洲日本波多野结衣| 国精品人妻无码一区免费视频电影 | 国产精品一二三中文字幕| 免费无码一区无码东京热| 久久精品国产亚洲av麻豆小说 | 又大又粗又爽18禁免费看| 激情综合色综合久久综合| 夜夜躁狠狠躁2021| 精品视频一区二区福利午夜 | 日韩av片无码一区二区不卡 | 亚洲人成网线在线播放VA| 久章草在线毛片视频播放| 久久亚洲国产精品久久| 日韩人妻中文字幕精品| 成人欧美一区二区三区在线观看| 国内精品久久久久影院蜜芽|