【问题标题】:How to avoid circular dependency with template method如何使用模板方法避免循环依赖
【发布时间】:2018-07-01 16:54:44
【问题描述】:

所以,我一直在从事系统 API 的项目,我试图弄清楚如何在静态模板方法的定义中避免循环依赖。问题是,模板方法不能在单独的 cpp 中定义,我也不能在头文件中定义它,因为这会导致循环依赖:

流.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”的循环依赖。

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

【问题讨论】:

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


    【解决方案1】:

    flow.h中去掉flowImpl.h#include,并前向声明模板类方法:

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

    【讨论】:

      猜你喜欢
      • 2013-02-06
      • 1970-01-01
      • 2018-09-03
      • 2012-02-15
      • 2013-04-02
      • 1970-01-01
      • 1970-01-01
      • 2012-08-10
      • 1970-01-01
      相关资源
      最近更新 更多