2017-08-09 34 views
0

如果我有一個模板基類,需要派生類的類型,是安全的,這個基類的這個指針轉換爲派生類的類型?如果我將這個基類的指針轉換爲派生類型,它是否安全並定義好了?

考慮這個代碼,其中基類A將此指針轉換爲模板參數(Derived)。它還檢查提供的類型是否實際上是從這個類派生的。它顯然有效(在這裏),但是它有很好的定義?

#include <iostream> 

class D; 

template<typename Derived, typename T> 
class A 
{ 
public: 
    Derived *thisToDerived() { 
     static_assert(std::is_base_of< A<Derived, T>, Derived>::value, "not"); 
     return static_cast<Derived*>(this); 
    } 
private: 
    T m; 
}; 


class D : public A<D, int> 
{ 
private: 
    double d; 
    float f; 
}; 


int main() { 
    D d; 
    std::cout<<"this: "<<&d<<"\nderived: "<<d.thisToDerived(); 
} 
+0

相關:https://stackoverflow.com/q/2469013/1896169 – Justin

+0

也有關,幾乎可以解答:https://stackoverflow.com/q/4173254/1896169 – Justin

+0

簡單地說,是的,這是安全 – Justin

回答

2

如果我有一個模板基類,需要派生類的類型,是安全的this指針這個基類的強制轉換爲派生類的類型?
...
顯然,它的工作原理(在這裏),但它明確定義?

是的,它是安全的,並明確界定。它實際上是一個衆所周知的和常用的模式(見CRTP)以及又名靜態多態。用法

例子:


Derived *thisToDerived() { 
    // Your static_assert is superfluos 
    // static_assert(std::is_base_of< A<Derived, T>, Derived>::value, "not"); 
    return static_cast<Derived*>(this); 
     // ^^^^^^^^^^^^^^^^^^^^^ 
     // Already guarantees that Derived is inherited from A 
} 
+0

迂迴模式:CRTP是一種成語,而不是模式。 – skypjack

+1

@skypjack好,挑剔回:至少在CRTP的_P_代表_Pattern_ ;-) – user0042

相關問題