简体   繁体   English

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

[英]How to avoid circular dependency with template method

So, i've been working in a project of a System API, and i'm trying to figure out how to avoid circular dependency in the definition of a static template method. 因此,我一直在研究System API的项目,并且试图解决如何避免静态模板方法定义中的循环依赖。 The thing is, template methods cannot be defined in a separeted cpp, and i cannot define it in the header file either because that would cause circular dependency: 关键是,模板方法不能在单独的cpp中定义,我也不能在头文件中定义它,因为那样会导致循环依赖:

flow.h: 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

I tried using forward declaration, but with no success, because i cannot forward declare a method of another class (being FlowImpl::createFlow()), only the entire class. 我尝试使用前向声明,但没有成功,因为我无法前向声明整个其他类的另一个类(即FlowImpl :: createFlow())的方法。

My objective in those static methods are to make a Method Factory with static members using interfaces, and since i cannot use "virtual" for static template methods, my only option was to implement it on the interface, and inside the implementation call the same static method but for the subclass, which have the atributes for allocation. 我在那些静态方法中的目标是使用接口使用具有静态成员的方法工厂,并且由于我不能对静态模板方法使用“虚拟”,因此我唯一的选择是在接口上实现它,并且在实现内部调用相同的static方法,但对于具有分配属性的子类。 As I said, I cannot do that either because template methods can't be implemented in a different file, and if I define it inside the header it will cause circular dependency with "flowImpl.h". 就像我说的那样,我不能这样做,因为模板方法不能在另一个文件中实现,并且如果我在标头中定义它,将导致与“ flowImpl.h”的循环依赖。

Thanks for reading! 谢谢阅读! Any ambiguities or lack of information please report so i can clarify it. 任何歧义或缺乏信息,请报告,以便我澄清。

Remove the #include of flowImpl.h from flow.h , and forward-declare the template class method: flow.h删除flowImpl.h#include ,并向前声明模板类方法:

class Flow {
public:

    // ...

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

Then finish the job in flowImpl.h , after the implementation class's declaration: 然后在实现类的声明之后,在flowImpl.h完成作业:

class flowImpl {

// ...

};

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

Do the same for the other template method, as well. 对其他模板方法也要这样做。 Note that whatever needs to call these class methods will have to include the flowImpl.h header file, though. 请注意,尽管需要调用这些类方法,但都必须包括flowImpl.h头文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM