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

时间:2018-07-01 16:54:45

标签: c++ templates interface static circular-dependency

因此,我一直在研究System 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”的循环依赖。

感谢您的阅读!任何歧义或缺乏信息,请报告,以便我澄清。

1 个答案:

答案 0 :(得分:2)

#include中删除flowImpl.h中的flow.h,并向前声明模板类方法:

class Flow {
public:

    // ...

    template <typename T_FLOW_IMPL>
    static Flow* createFlow();

然后在实现类的声明之后,在flowImpl.h中完成工作:

class flowImpl {

// ...

};

template <typename T_FLOW_IMPL>
static Flow* Flow::createFlow() {
    return FlowImpl::createFlow<T_FLOW_IMPL>();
}

对其他模板方法也执行相同的操作。请注意,尽管需要调用这些类方法,但都必须包含flowImpl.h头文件。