2016-09-03 6 views
1

私が試しているリファクタリングに問題があります。私たちは多くのコードの複製を持っており、これを整理しようとしています。私は、次のクラス構造にC++での抽象基本クラスとテンプレートを使用したリファクタリング

IMessageSink.hを持っている:

class IMessageSink 
{ 
public: 
    virtual ~IMessageSink() { }; 
    virtual void process(const taurus::Msg& msg) = 0; 
}; 

私は、この点をしてください使用しないで、すべてのモデルから継承する必要があり、以下の基本クラスModelBase.hを持っていますfriend class EM

class ModelBase : public virtual IMessageSink 
{ 
public: 
    ModelBase(Tag a); 

    void process(const taurus::Msg& msg); 
    void reset(); 

private: 
    friend class EM; // I will ask about this below. 

    virtual void calculate(double lambda) = 0; 
}; 

friend EMの実装が正しくないと、私は以下の本について尋ねます。 ModelM0.cpp

class ModelM0 : public virtual ModelBase 
{ 
public: 
    ModelM0(Tag a); 

    static ModelM0* ModelM0::make(Tag a) 
    { 
     ModelM0* m = new ModelM0(a); 
     m->reset(); 
     return m; 
    } 

private: 
    void calculate(double lambda); 
}; 

として実装::私は、/はModelBaseから継承実装するクラス、ModelM0.hを持って

ModelM0::ModelM0(Tag a) : ModelBase(a) { } 

void ModelM0::calculate(double lambda) 
{ 
    // Do stuff. 
} 

問題がEM友人のクラスであり、これを一般的な方法で実装する方法。これまでは、このクラスはModelBaseから継承しなかったタイプModelM0でのみ動作しました。今では他のモデルもModelBaseEMから継承する必要があります。これも問題になります。 EM.h

として:私は(私は、我々はTModelを使用しているModelBaseの種類を指定することができ、テンプレートに変更されている)EM.hで次の定義を持って

template <class TModel> 
class EM : public virtual IMessageSink 
{ 
public: 
    static EM* make(Tag a) 
    { 
     return new EM(a); 
    } 

    EM(Tag a); 
    ~EM(); 

    void process(const taurus::Msg& msg); 
    void run(); 
private: 
    struct Bucket 
    { 
     TModel* _model; 
     std::vector<TinyMatrix<1, 1> > _obs 
    }; 

    EM::Bucket& getModel(int ag); 
} 

問題の実装では、我々は上記のは大丈夫であるように思わ

template<class TModel> 
EM<TModel>::EM(Tag a) { } 

template<class TModel> 
EM<TModel>::~EM() 
{ 
    run(); 
} 

template<class TModel> 
void EM<TModel>::process(const taurus::Msg& msg) 
{ 
    int ag = getMessageCount(msg.type()); // External call. 
    if (ag <= 3) 
    { 
     Bucket& b = getModel(ag); 
     TModel* m = b._model; 
     m->process(msg); 
    } 
} 

を持ってEM.cppで、EM::Bucket& getModel(int ag);で、私の問題がありますgetModel

template<class TModel> 
EM<TModel>::Bucket& EM<TModel>::getModel(int ag) 
{ 
    // This is not right. 
    TModel* m; 
    m = TModel::make(getTag(ag)); // This is not right - I need a factory. 

    // ... Do stuff. 

    Bucket& b = // Get a bucket. 
    b._model = m; 

    return b; 
} 

私の質問の実装:EM<TModel>::getModel(int ag)に私は正しいTModelは、上記にmakeを使用して作成することができるように、私は上記のコードを変更するにはどうすればよい

  1. は - 私は工場​​が必要ですし、これはどのように実装されますか?

  2. ModelBase.hEMクラスはフレンドクラスとして指定されます。どのように私はTModelModelBase)タイプが使用されている状態でジェネリックを動作させることができますか?

私が方法に示されているコードは(これは簡潔に強調するために伐採された正しいか正しくありませんではないか、または-、これはリファクタリングの質問であることをここで注意することは重要です私の問題)。リファクタリングだけが私が助けてくれることです。あなたのお時間をありがとう。私はあなたのコードがコンパイルを取得しようとしたとき

+1

はい、コードがコンパイルされないためです。コードレビューは実際の作業例のみです... – MoonKnight

+1

'私は工場を必要とし、どのように実装するのですか? '工場のパターンは、作成されたオブジェクトが結合されて、 –

+0

コンパイラのエラーを追加してください。 – grek40

答えて

1

は、私はあなたがする必要がある、いくつか欠けているセミコロンや不足しているタイプ(Tagtaurus::MsgTinyMatrix)を固定し、また、一般的にgetModel(int ag)

の宣言と定義を修正しなければなりませんでしたコンパイラに対して、Bucketは実際には型名であり、他の種類のパラメータではないことを示します。宣言のために

あなたは2つのオプションがあります:

Bucket& getModel(int ag); // (1) 
typename EM<TModel>::Bucket& getModel(int ag); // (2) 

(1)あなたの現在のテンプレートの特殊化のバケツ型の暗黙の使い方ですが。 (2)は、上記のように、コンパイラのキーワードtypenameと明示的な型の使用です。

あなたがクラス定義コンテキストから外れているので、あなたは確かにtypenameキーワードが必要です。

template<class TModel> 
typename EM<TModel>::Bucket& EM<TModel>::getModel(int ag) 
{ 
    // This is not right. 
    TModel* m; 
    m = TModel::make(getTag(ag)); // This is not right - I need a factory. 

    // ... Do stuff. 

    Bucket& b = // Get a bucket. 
     b._model = m; 

    return b; 
} 

「これは正しくありません。」を無視してください。コメント - サンプルコードからコピーしました。実際には完全に正しい。

friend宣言では、可能なすべてのテンプレートインスタンス化をしたいので、テンプレートバージョンを追加する必要があります。私はすべてのあなたの問題を解決し

・ホープ(Anycornにクレジット)this answerからそれを見上げました。使用して以来、私はtemplate <class>を使用しました。個人的に私はtemplate <typename>を好む。

+0

私はちょうど質問を再読した。私がまだ検討していなかった「友人」の面を見るだろう。しかし、ほとんどの場合、「友人」を必要とすることは、基礎となる設計上の問題の指標である。 – grek40

+0

ご協力いただきありがとうございます。私はあなたの提案された変更を実装し、コンパイルエラーで戻ってきます... – MoonKnight

+0

@Killercamは私の編集を一番下に見ます。 – grek40

関連する問題