close

<article class="mx-1 my-1">
<h4>正文</h4>

稍微了解過template以後,我們就可以看懂以下的程式碼(這邊用class而非typename,是想表明_Derived只會是一個使用者自訂型別):
<!--more-->
<pre>----main.cpp
    #include 
    using namespace std;

    template
    class base {
    public:
        void foo() {
            cout << "base\n";
        }
        _Derived getDerive() {
            return _Derived();
        }
    };

    class derive: public base {
    public:
        void foo() {
            cout << "derive\n";
        }
    };
    int main () {
        base b;
        derive d;
        
        b.foo();
        b.getDerive().foo();
        d.foo();
        
        return 0;
    }

----output:
    base
    derive
    derive
</pre>
這邊看到一個情境,Binary Tree跟AVL Tree概念上都有一組左右子樹,
但兩棵樹的成員不同,AVL多了一個平衡因子(Balance factor),
因此我想要利用繼承,並回傳左右節點,就必須知道使用者是宣告哪棵樹,
這時CRTP就派上用場了,我們可以經由template得知AVL Tree的類別,並藉此當作回傳型別,
這邊的例子一併也會看到與泛型類別搭配的用法:
<pre>----main.cpp
    include 
    using namespace std;

    template
    class bt {
    public:
        typedef _Derived derived_type;
        derived_type* left() { return new derived(); }
        derived_type* right() { return new derived(); }
    };

    template
    class avl : public bt{    //注意這邊的宣告方式
    public:
        long bf;
        avl(): bf(0) {};
    };

    int main () {
        bt b;
        avl c;
        cout << typeid(b).name() << endl;
        cout << typeid(*b.left()).name() << endl;
        cout << typeid(c).name() << endl;
        cout << typeid(*c.left()).name() << endl;
        
  //    cout <<b>bf << endl; // error, bt沒有bf這個屬性
        cout <bf << endl;

        return 0;
    }

----output:
    bf
    int
    avl
    avl
    0
</pre>
<h4>參考資料</h4>

<ol>
    <li><a href="https://stackoverflow.com/questions/4173254/what-is-the-curiously-recurring-template-pattern-crtp">stack overflow的討論</a></li>
</ol>
</article>

arrow
arrow

    Ernest 發表在 痞客邦 留言(0) 人氣()