![](/img/trans.png)
[英]CRTP - How to call the base class implemention of a method from the derived class?
[英]Does the derived class method override the base class version of the method in case the CRTP is used?
幾天前,我發現了一個有趣的 C++ 結構,名為 Curiously Recurring Template Pattern (通常縮寫為 CRTP)。 從那時起,我一直試圖完全理解這個技巧是如何工作的。
假設我有以下代碼片段
#include <iostream>
template<class T>
struct GraphicalObject
{
void draw()
{
static_cast<T*>(this)->draw();
}
};
struct Circle : GraphicalObject<Circle>
{
void draw()
{
std::cout << "Drawing circle!" << std::endl;
}
};
struct Square : GraphicalObject<Square>
{
void draw()
{
std::cout << "Drawing square!" << std::endl;
}
};
int main(int argc, char** argv) {
Square s;
Circle c;
s.draw();
c.draw();
return 0;
}
CRTP 背后的所有“魔法”顯然都在static_cast<T*>(this)->draw()
行中。 但它是如何詳細工作的? 我的理解如下。 假設我有Circle c
。
萬一編譯器看到這個聲明,這是他用參數Circle
實例化GraphicalObject
模板的信號。 我認為這會導致編譯器創建 struct GraphicalObject<Circle>
struct GraphicalObject<Circle>
{
void draw()
{
static_cast<Circle*>(this)->draw();
}
};
因此創建了具有特殊版本的draw
方法的 struct。 struct GraphicalObject<Circle>
forms 是Circle
結構的基礎結構。
在第二步中,創建Circle
結構的實例c
,即調用Circle
的隱式構造函數。 由於Circle
是從GraphicalObject<Circle>
繼承的,因此首先調用該結構的隱式構造函數。 在我看來,這會導致在c
object 中創建GraphicalObject<Circle>
的實例。 這樣對嗎? 然后我認為Circle
結構中聲明的draw
方法覆蓋了GraphicalObject<Circle>
結構中聲明的draw
方法。 但這對我來說沒有意義。 我寧願期望來自GraphicalObject<Circle>
的draw
方法的“專用”版本不應被覆蓋。 請你能告訴我我對 CRTP 工作原理的理解有什么問題嗎?
你沒有在main
中做任何多態的事情來展示 CRTP 的特性。 試試這個,看看會發生什么:
template <typename T>
void drawObject(GraphicalObject<T>& obj) {
obj.draw();
}
int main() {
Square s;
Circle c;
s.draw();
c.draw();
drawObject(s); // what happens here?
GraphicalObject<Circle>& c_ref = c;
drawObject(c_ref); // what happens here?
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.