如何使用模板方法避免循环依赖
How to avoid circular dependency with template method
所以,我一直在系统 API 的一个项目中工作,我试图找出如何避免静态模板方法定义中的循环依赖。问题是,模板方法不能在单独的 cpp 中定义,我也不能在 header 文件中定义它,因为那样会导致循环依赖:
flow.h:
#include "system.h"
#include "flowImpl.h" //circular dependency
#include <vector>
#ifndef TRAB_INDIVIDUAL_FLOW_H
#define TRAB_INDIVIDUAL_FLOW_H
typedef std::vector<System*>::iterator SystemIterator;
class Flow {
public:
//-----------------------------------
//What's giving me problems
template <typename T_FLOW_IMPL>
static Flow* createFlow() {
return FlowImpl::createFlow<T_FLOW_IMPL>();
}
template <typename T_FLOW_IMPL>
static Flow* createFlow(System* s1,System* s2,std::string str) {
return FlowImpl::createFlow<T_FLOW_IMPL>(s1,s2,str);
}
//-----------------------------------
virtual double executeFunction()=0;
virtual System* getTargetSys()=0;
virtual System* getSourceSys()=0;
virtual std::string getName()=0;
virtual void changeTargetSys(SystemIterator)=0;
virtual void changeSourceSys(SystemIterator)=0;
virtual void changeTargetSys(System*)=0;
virtual void changeSourceSys(System*)=0;
};
#endif
flowImpl.h
#include "flow.h"
#ifndef TRAB_INDIVIDUAL_FLOWIMPL_H
#define TRAB_INDIVIDUAL_FLOWIMPL_H
class ModelImpl;
class FlowImpl : public Flow {
friend ModelImpl;
friend Flow;
private:
FlowImpl();
FlowImpl(System*,System*,std::string);
FlowImpl(Flow*,std::string);
std::string name;
System* source_sys;
System* target_sys;
template <typename T_FLOW_IMPL>
static Flow* createFlow() {
Flow* f = new T_FLOW_IMPL();
return f;
}
template <typename T_FLOW_IMPL>
static Flow* createFlow(System*,System*,std::string) {
Flow* f = new T_FLOW_IMPL(s1,s2,str);
return f;
}
protected:
double getSourceQ();
double getTargetQ();
public:
virtual ~FlowImpl();
bool operator==(FlowImpl&);
FlowImpl& operator=(const FlowImpl&);
virtual double executeFunction()=0;
System* getTargetSys() override;
System* getSourceSys() override;
std::string getName() override;
void changeTargetSys(SystemIterator) override;
void changeSourceSys(SystemIterator) override;
void changeTargetSys(System*) override;
void changeSourceSys(System*) override;
};
#endif
我尝试使用前向声明,但没有成功,因为我无法前向声明另一个 class(即 FlowImpl::createFlow())的方法,只能前向声明整个 class。
我在这些静态方法中的 objective 是使用接口创建一个带有静态成员的方法工厂,并且由于我不能将 "virtual" 用于静态模板方法,我唯一的选择是在接口和内部实现调用相同的静态方法,但对于 subclass,它具有分配属性。正如我所说,我也不能这样做,因为模板方法不能在不同的文件中实现,如果我在 header 中定义它,它将导致 "flowImpl.h".[=12= 的循环依赖]
感谢阅读!如有任何歧义或信息不足,请报告,以便我进行澄清。
从 flow.h
中删除 flowImpl.h
的 #include
,并向前声明模板 class 方法:
class Flow {
public:
// ...
template <typename T_FLOW_IMPL>
static Flow* createFlow();
然后在flowImpl.h
完成作业,执行完class的声明:
class flowImpl {
// ...
};
template <typename T_FLOW_IMPL>
static Flow* Flow::createFlow() {
return FlowImpl::createFlow<T_FLOW_IMPL>();
}
对另一个模板方法也做同样的事情。请注意,无论需要调用这些 class 方法,都必须包含 flowImpl.h
头文件。
所以,我一直在系统 API 的一个项目中工作,我试图找出如何避免静态模板方法定义中的循环依赖。问题是,模板方法不能在单独的 cpp 中定义,我也不能在 header 文件中定义它,因为那样会导致循环依赖:
flow.h:
#include "system.h"
#include "flowImpl.h" //circular dependency
#include <vector>
#ifndef TRAB_INDIVIDUAL_FLOW_H
#define TRAB_INDIVIDUAL_FLOW_H
typedef std::vector<System*>::iterator SystemIterator;
class Flow {
public:
//-----------------------------------
//What's giving me problems
template <typename T_FLOW_IMPL>
static Flow* createFlow() {
return FlowImpl::createFlow<T_FLOW_IMPL>();
}
template <typename T_FLOW_IMPL>
static Flow* createFlow(System* s1,System* s2,std::string str) {
return FlowImpl::createFlow<T_FLOW_IMPL>(s1,s2,str);
}
//-----------------------------------
virtual double executeFunction()=0;
virtual System* getTargetSys()=0;
virtual System* getSourceSys()=0;
virtual std::string getName()=0;
virtual void changeTargetSys(SystemIterator)=0;
virtual void changeSourceSys(SystemIterator)=0;
virtual void changeTargetSys(System*)=0;
virtual void changeSourceSys(System*)=0;
};
#endif
flowImpl.h
#include "flow.h"
#ifndef TRAB_INDIVIDUAL_FLOWIMPL_H
#define TRAB_INDIVIDUAL_FLOWIMPL_H
class ModelImpl;
class FlowImpl : public Flow {
friend ModelImpl;
friend Flow;
private:
FlowImpl();
FlowImpl(System*,System*,std::string);
FlowImpl(Flow*,std::string);
std::string name;
System* source_sys;
System* target_sys;
template <typename T_FLOW_IMPL>
static Flow* createFlow() {
Flow* f = new T_FLOW_IMPL();
return f;
}
template <typename T_FLOW_IMPL>
static Flow* createFlow(System*,System*,std::string) {
Flow* f = new T_FLOW_IMPL(s1,s2,str);
return f;
}
protected:
double getSourceQ();
double getTargetQ();
public:
virtual ~FlowImpl();
bool operator==(FlowImpl&);
FlowImpl& operator=(const FlowImpl&);
virtual double executeFunction()=0;
System* getTargetSys() override;
System* getSourceSys() override;
std::string getName() override;
void changeTargetSys(SystemIterator) override;
void changeSourceSys(SystemIterator) override;
void changeTargetSys(System*) override;
void changeSourceSys(System*) override;
};
#endif
我尝试使用前向声明,但没有成功,因为我无法前向声明另一个 class(即 FlowImpl::createFlow())的方法,只能前向声明整个 class。
我在这些静态方法中的 objective 是使用接口创建一个带有静态成员的方法工厂,并且由于我不能将 "virtual" 用于静态模板方法,我唯一的选择是在接口和内部实现调用相同的静态方法,但对于 subclass,它具有分配属性。正如我所说,我也不能这样做,因为模板方法不能在不同的文件中实现,如果我在 header 中定义它,它将导致 "flowImpl.h".[=12= 的循环依赖]
感谢阅读!如有任何歧义或信息不足,请报告,以便我进行澄清。
从 flow.h
中删除 flowImpl.h
的 #include
,并向前声明模板 class 方法:
class Flow {
public:
// ...
template <typename T_FLOW_IMPL>
static Flow* createFlow();
然后在flowImpl.h
完成作业,执行完class的声明:
class flowImpl {
// ...
};
template <typename T_FLOW_IMPL>
static Flow* Flow::createFlow() {
return FlowImpl::createFlow<T_FLOW_IMPL>();
}
对另一个模板方法也做同样的事情。请注意,无论需要调用这些 class 方法,都必须包含 flowImpl.h
头文件。