Итак, я работаю в проекте системного API и пытаюсь выяснить, как избежать циклической зависимости в определении метода статического шаблона. Дело в том, что методы шаблона не могут быть определены в отдельном cpp, и я не могу определить его в заголовочном файле, потому что это может вызвать циклическую зависимость:
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
Я попытался использовать прямое объявление, но безуспешно, потому что я не могу переслать объявление метода другого класса (являющегося FlowImpl :: createFlow ()), только всего класса.
Моя цель в этих статических методах состоит в том, чтобы создать фабрику методов со статическими членами, использующими интерфейсы, и, поскольку я не могу использовать «виртуальный» для статических шаблонных методов, единственным вариантом было реализовать его на интерфейсе и внутри вызова реализации. тот же статический метод, но для подкласса, у которого есть атрибуты для распределения. Как я уже сказал, я не могу этого сделать, потому что методы шаблона не могут быть реализованы в другом файле, и если я определю его внутри заголовка, это вызовет циклическую зависимость с помощью flowImpl.h.
Спасибо за чтение! Пожалуйста, сообщайте о любых неясностях или отсутствии информации, чтобы я мог уточнить это.