C++ 在C+中使用抽象基类和模板进行重构+;

C++ 在C+中使用抽象基类和模板进行重构+;,c++,templates,inheritance,refactoring,class-design,C++,Templates,Inheritance,Refactoring,Class Design,我在尝试重构时遇到了问题。我们有很多代码重复,我正在努力解决这个问题。我的班级结构如下 IMessageSink.h: class IMessageSink { public: virtual ~IMessageSink() { }; virtual void process(const taurus::Msg& msg) = 0; }; class ModelM0 : public virtual ModelBase { public: ModelM0(Tag

我在尝试重构时遇到了问题。我们有很多代码重复,我正在努力解决这个问题。我的班级结构如下

IMessageSink.h

class IMessageSink
{
public:
    virtual ~IMessageSink() { };
    virtual void process(const taurus::Msg& msg) = 0;
};
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.h,所有模型都必须从中继承,此时请不要使用
友元类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
的实现不正确,我在下面询问这一点。然后我有一个类,它实现/继承了
ModelBase
ModelM0.h

class IMessageSink
{
public:
    virtual ~IMessageSink() { };
    virtual void process(const taurus::Msg& msg) = 0;
};
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);
};
使用ModelM0.cpp实现为:

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

void ModelM0::calculate(double lambda)
{
    // Do stuff.
}
问题在于
EM
friend类以及如何以通用方式实现它。以前,这个类只处理类型
ModelM0
,而不是从
ModelBase
继承。现在,其他模型也继承自
ModelBase
EM
也需要使用这些模型-问题就在这里。我在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);
}
上面的内容似乎没有问题,我的问题是
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::Bucket&EM::getModel(int-ag)
{
//这是不对的。
t模型*m;
m=TModel::make(getTag(ag));//这不对-我需要一个工厂。
//…做事。
Bucket&b=//获取一个Bucket。
b、 _model=m;
返回b;
}
我的问题是:

  • 如何更改上述代码,以便在
    EM::getModel(int-ag)
    中使用上述
    make
    创建正确的
    TModel
    -我需要工厂吗?这将如何实现

  • ModelBase.h
    中,将
    EM
    类指定为友元类。如何将此me设置为泛型,以便与正在使用的
    TModel
    ModelBase
    )类型一起使用


  • 这里需要注意的是,这是一个重构问题,而不是我在方法中显示的代码是否正确或正确(为了简洁地突出我的问题,我们减少了这个问题)。重构是我唯一需要帮助的事情。非常感谢您的时间。

    当我试图编译您的代码时,我必须修复一些缺少的分号和类型(
    标记
    taurus::Msg
    TinyMatrix
    ),还必须修复
    getModel(int ag)

    通常,您需要向编译器指出,
    Bucket
    实际上是一个类型名,而不是其他类型的参数

    对于声明,您有两个选项:

    Bucket& getModel(int ag); // (1)
    typename EM<TModel>::Bucket& getModel(int ag); // (2)
    
    忽略“This is not right.”注释-我从示例代码中复制了它们。事实上,这是完全正确的

    对于
    friend
    声明,您需要添加一个模板版本,因为您希望与所有可能的模板实例化成为朋友。我从(信用卡到Anycorn)上查到的

    模板好友类EM;
    

    希望这能解决你所有的问题。注意:自从您使用了
    模板后,我就使用了它。就我个人而言,我更喜欢
    模板

    是的,因为代码无法编译。代码审查仅用于工作示例…我是否需要工厂以及如何实现此功能?当创建的对象包含可耦合在一起构造给定对象功能的通用部分时,通常会考虑工厂模式…请添加编译器错误。我只是重新阅读了问题。要看<代码>朋友<代码>方面,我还没有考虑。然而,大多数时候,需要
    朋友
    是潜在设计问题的指标。非常感谢您的帮助和时间。我将实现您建议的更改,并返回编译器错误…非常感谢您的时间。这就成功了。这段代码进行编译,并像在这次重大更改之前一样完美地运行。非常感谢你的时间。再次感谢你。。。
    template <class> friend class EM;