2017-08-09 15 views
0

派生クラスの型をとるテンプレート基本クラスがある場合、この基本クラスのthisポインタを派生クラスの型にキャストするのは安全ですか?基本クラスのthisポインタを派生型にキャストした場合、安全であり、守れませんか?

基本クラス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

Pedantic mode on:CRTPはパターンではなく、イディオムです。 – skypjack

+1

@skypjackさて、ニックピッキングバック:少なくともCRTPの_P_は_Pattern_ ;-)の略です。 – user0042