此为历史版本和 IPFS 入口查阅区,回到作品页
eopXD
IPFS 指纹 这是什么

作品指纹

CRTP

eopXD
·
·

CRTP 全名 Curiously Recurring Template Pattern ,又被稱作 F-bound polymorphism ,F-bound quantification 中的一種形式。故事要先從型態轉型開始。

A general function for all derived class

常常會遇到從同一個 base class 繼承下來許多子類別,而會希望對這些子類別有一些通用的函數可以呼叫。這時在 runtime 才能得知子類別,但是想要把它轉型時無從下手。這裡以 Shape 與可能繼承 Shape 這個 class 的子類別來做舉例:

class Shape {}
class Square : public Shape {}
class Circle : public Shape {}
class Octagon : public Shape {}
void copyShape (Shape *shape) {
  Shape copied = new ????(*shape); // we don't know the derived type
}

這時一般會寫在 base class 寫一個 virtual function ,並要求繼承的子類別都去 override 。如下:

class Shape {
public:
  virtual Shape* clone () const = 0;
};
class Square : public Shape {
public:
  virtual Square *clone() const { return new Square(*this); }
}
class Circle : public Shape {
public:
  virtual Circle *clone() const { return new Circle(*this); }
}
class Octagon : public Shape {
public:
  virtual Octagon *clone() const { return new Octagon(*this); }
}

壞處:對每個子類別都要寫一個自己的 clone ,會出現大量長得很像卻又重複的程式碼

General form of CRTP

// The Curiously Recurring Template Pattern (CRTP)
template <class T>
class Base
{
    // methods within Base can use template to access members of Derived
};
class Derived : public Base<Derived>
{
    // ...
};

What does it solve?

透過 CRTP 就對通用的函數就不用再寫一遍。

class Shape
{
public:
    virtual Shape* clone() const = 0;
};
 
template <typename Derived>
class CloneableShape : public Shape
{
public:
    virtual Derived* clone() const {
        return new Derived(static_cast<Derived const&>(*this));
    }
};

等於對 base class template 基於 自己(derived class) 「再 derive」出最終想要的,具有完整功能的 derived class 。這個就是 CRTP 。

class Square : public CloneableShape<Square> {};

如果你覺得我寫的東西是有價值的,可以用 PayPal 支持我

如果喜歡的事情能帶來不只是快樂的報酬,那自然是再好不過了!

NT$30.00

Click here to purchase.

Original link: eopXD

CC BY-NC-ND 2.0 授权