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