如何使用模板方法避免循环依赖

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 头文件。