C++ 在C+中使用抽象基类和模板进行重构+;
我在尝试重构时遇到了问题。我们有很多代码重复,我正在努力解决这个问题。我的班级结构如下 IMessageSink.h: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
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;