2012-02-01 9 views
1

Timer.h:C++多型

TimerImpl.h:

class TimerImpl: public Timer<long> { 
public: 

TimerImpl() { 
} 

~TimerImpl() { 

} 

long get(); 

}; 

FpsMeter.h(バージョン1):

template <class T> 
class FpsMeter { 
    private: 
    Timer<T>* timer; 

    public: 
    FpsMeter (Timer<T>* timer) { 
     this->timer = timer; 
    } 

    ... 

}; 

この例では、動作します。しかしそれはかなり見えません。

Timer<long>* t = new TimerImpl(); 
FpsMeter<long>* f1 = new FpsMeter<long> (t); 

ここでは、追加のテンプレートがたくさん使用されています。どのように私はマルチタイプのインターフェイスのこのアイデアを実現することができますタイプは、実装によって定義され、ユーザークラスは新しいタイプを定義していない、それは実装のタイプを使用する必要があります。

+1

あなたFpsMeterクラスが多型にする必要がありますか? –

+0

get()が異なる型を返すようなインタフェースのバージョンを望むなら、テンプレートはAFAIUを行う方法です。 –

+0

@Kerrek SBはい、あります。私は別のタイマーを使いたい。 – itun

答えて

1

あなたは常に、あなたは可能性が次

template < class T > 
FpsMeter<T> *make_FpsMeter(Timer<T> *timer) { 
    return new FpsMeter<T>(timer); 
    } 

次に、適切なタイプのFpsMeterを作成するような何かがそう

FpsMeter<long> *f1 = make_FpsMeter(new TimerImpl()); 
のようなものであるヒープ上FpsMeterを作成するヘルパテンプレート関数を気にしない場合

それとも、C++ 11の自動車を使用することができれば、あなたは

auto f1 = make_FpsMeter(new TimerImpl()); 
1

これは私が知る限り、C++でできることは最高です。 FpsCounterは、どのTimer<T>実装が受け入れることができるかを知るために、タイプTを知る必要があります。あなたのサンプルコードはやや簡素化することができます。少なくとも、その場合FpsMeterにテンプレートの種類を繰り返すのあなたを取得しますが、当然の

FpsMeter<long>* f1 = new FpsMeter<long> (new TimerImpl()); 

が... auto_ptrを通じて理想的に、TimerImplを削除するための責任を取る必要がありますまたはそのような。

戻り値を実際にget()に変更する必要があるかどうかは疑問です。 longのほかに、どんな値が返されると思いますか?

1

たぶんCを取得したいですC++ 11の<chrono> libraryからインスピレーションを受けてください(これもまた追加で利用可能です)。それとも、自分の時間を節約して、それを直接使用する方が良いでしょう。効率的で、安全で、柔軟性があり、使いやすいです。あなたは(私は仮定し、全プログラムのコンパイル段階で定義されなければならない)、機械タイマーの実装に基づいてのみ、タイマーを使用する場合は

0

、私は単に右のそれを得るためにtypedefと、おそらくいくつかのプリプロセッサの魔法を使用します。

[...] 
#if TIMER_LONG // Here you should somehow check what type is used on target platform. 
    typedef Timer<long> implTimer; 
    typedef FpsMeter<long> implFpsMeter; 
#else // If eg. using double? 
    typedef Timer<double> implTimer; 
    typedef FpsMeter<double> implFpsMeter; 
#fi 

これは、implTimerとimplFpsMeterを使用している限り、使用されている実際のタイプをユーザーコードが認識しないようにします。あなたは、コードの一部が異なるTimerImplを使用することを意味している場合

あなたは `タイマー `別のインタフェースのための任意の*理由*があります

class FpsMeter{ 
public: 
    virtual double fps()=0; 
    virutal void newFrame()=0; 
    [...] 
    //Class counts new frames and using internal timer calculates fps. 
}; 

template <typename T> 
class FpsMeterImpl: public FpsMeter{ 
    TimerImpl<T>* timer; 
public: 
    FpsMeterImpl(TimerImpl<T>* timer); 

    virtual double fps(); 
    virutal void newFrame(); 
};