在類層次結構的設計中,我使用抽象基類來聲明派生類將實現的各種方法。從某種意義上說,基類與C++中的接口非常接近。但是,有一個具體問題。考慮下面這宣告我們的接口類的代碼:在基類中返回抽象類型
class Interface {
public:
virtual Interface method() = 0;
};
class Implementation : public Interface {
public:
virtual Implementation method() { /* ... */ }
};
當然,這不會編譯,因爲你不能用C返回一個抽象類++。爲了解決這個問題,我用以下解決方案:
template <class T>
class Interface {
public:
virtual T method() = 0;
};
class Implementation : public Interface<Implementation> {
public:
virtual Implementation method() { /* ... */ }
};
此解決方案是所有罰款和花花公子,但是,對我來說,它看起來並不很優雅,因爲文字的冗餘位這將是接口的參數。如果你們可以用我們的設計指出其他技術問題,我會很高興,但這是我唯一關心的問題。
有什麼辦法擺脫冗餘模板參數?可能使用宏?
注意:有問題的方法必須返回一個實例。我知道如果method()
返回一個指針或引用,那就沒有問題了。
您正在使用的習語稱爲[好奇地重複出現的模板圖案](http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Curiously_Recurring_Template_Pattern)。我想你可以用像'#define DERIVE_TEMPLATE_BASE(Derived,Base)class Derived:public Base'這樣的宏替換類聲明,但它看起來非常難看,並且可能會讓你的編輯器感到困惑。底線 - 是的,有一個冗餘,但它是完善和可識別的習慣用法。 –
gwiazdorrr
@gwiazdorrr:這看起來不錯。如果這是一個公認的習慣用法,那麼我可以假設它對於「界面」的用戶來說不會太陌生,對嗎? – Zeenobit
另外需要注意的是(至少在本例中),將呼叫設爲虛擬是沒有意義的,因爲CRTP需要知道使用基本類型的最多派生類型。 –