1

私はこの3つのクラスを持っています。

class A  
{  
    public:  
        virtual void Func() = 0;  
};

template<class T>  
class B : public A  
{  
    public:  
        void Func()  
        {  
            cout << "In B" << endl;  
            static_cast<T*>(this)->Func();  
        }  
};  

class C : public B<C>  
{  
    public:  
        void Func()  
        {  
            cout << "In C" << endl;  
        }  
};  

そして、私はこれを行います:

int main(int argc, char **argv)  
{  
    A *a = new C;  
    a->Func();  

    return 0;  
}  

そして、「Cで」と表示されます。

私がこれを行うと、

int main(int argc, char **argv)  
{  
    B<C> *a = new C;  
    a->Func();  

    return 0;  
}  

再び「In C」と表示されます

何が起こっている?

4

3 に答える 3

1

この関数をオーバーロードしたクラス C オブジェクトの仮想メンバー関数を呼び出しています。クラス C の関数を呼び出します。

さらに、テンプレート化されたクラス B はクラス テンプレート パラメータから継承しないため、これは CRTP ではありません。

于 2010-02-24T10:44:49.243 に答える
1

Funcは仮想で、aは のインスタンスへのポインタであるCため、CのバージョンのFuncが呼び出されます。

于 2010-02-24T10:51:50.810 に答える
0

コードは完全ではありません。#include と「using namespace std;」を追加してください。さらに重要なことは、A の仮想関数宣言を削除することで、目的の動作が得られることです。一般に、CRTP を使用する主な理由は、テンプレートに受け取る型を知らせ、仮想呼び出しを行わないようにすることです (または、メソッドの作成を避けることをお勧めします)。バーチャル)。

template <typename T>
class ClassUsingSomething {
  public:
    void method1() {
      // I need to call method2, I do this by casting, so it doesn't need to be virtual.
      static_cast<T *>(this)->method2();
    }
};

class A: public ClassUsingSomething<A> {
  public:
    void method2() {
      //do something
    }
};
于 2010-05-05T16:58:06.580 に答える