【问题标题】:Inheritance from Template Class从模板类继承
【发布时间】:2018-01-18 20:38:30
【问题描述】:

我正在尝试实现一个 FSM 类,为了使其更通用,我决定使用模板类;但是,我收到了一些错误。错误不是很清楚(感谢 Xcode),但我认为问题在于我如何声明我的类和处理继承等。

更新:

错误:

这是我的代码:

FiniteStateMachine.hpp

---------------------------------
template<class RETURNS, typename PARAMS>
class BaseState
{
public:
    // For forcing all the classes have this method
    virtual std::vector<RETURNS> performDecision(PARAMS& pList) = 0;
};

template<class R, typename P>
class FSM_State : public BaseState<R, P>
{
public:

    FSM_State(int pStateNum = 0);
    virtual ~FSM_State();

    void init(int pStateNum = 0);

    void addState(FSM_State<R,P>* pState);
    void addState(const int pIndex, FSM_State<R,P>* pState);

    virtual std::vector<R> performDecision(P& pList) = 0;

protected:

    std::vector<FSM_State*> mStateList;
};


OHB_DT_FSM.hpp

-----------------------------------------

class OHB_DT_FSM_State : public FSM_State<eDECISION_TYPES, GameAI>
{
public:

    OHB_DT_FSM_State(int pStateNum = 0)
        : FSM_State(pStateNum)
    {}

    virtual ~OHB_DT_FSM_State()
    {
        delete mDecisionTree;
    }

    virtual void constructDT() = 0;

    virtual std::vector<eDECISION_TYPES> performDecision(GameAI& pList) = 0;

protected:

    eSTATE_TYPES mType;

    std::vector<eDECISION_TYPES> mDecisionList;

    DecisionTree* mDecisionTree;
};

这就是我处理继承的方式,但由于我对模板没有经验,所以我不确定我的方法。

对于 .hpp 文件中未描述的每种方法,我都有 .cpp 文件中的代码。

CPP 文件:

template<class R, typename P>
FSM_State<R, P>::FSM_State(int pStateNum)
{
    init(pStateNum);
}

template<class R, typename P>
FSM_State<R, P>::~FSM_State()
{
    for(int si = 0; si < mStateList.size(); si++)
    {
        delete mStateList[si];
    }

    mStateList.clear();
}

template<class R, typename P>
void FSM_State<R, P>::init(int pStateNum)
{
    if(pStateNum > 0)
    {
        mStateList.resize(pStateNum);
    }
}

template<class R, typename P>
void FSM_State<R, P>::addState(FSM_State* pState)
{
    mStateList.push_back(pState);
}

template<class R, typename P>
void FSM_State<R, P>::addState(const int pIndex, FSM_State* pState)
{
    mStateList[pIndex] = pState;
}

谢谢!

【问题讨论】:

  • 您将要重新定义函数是一个 cpp 文件:stackoverflow.com/questions/495021/…
  • 有什么错误?你可能不清楚,但其他人可能不清楚
  • 函数定义似乎正确,cpp 文件和错误代码已添加@NathanOliver

标签: c++ templates inheritance pure-virtual


【解决方案1】:

在声明虚函数时,考虑最后的部分:

  • = 0; 表示纯虚拟函数,这意味着该函数必须由派生类实现
  • override; 表示您正在重写基类中的虚函数

在您的示例中,您只使用= 0; - 但FSM_StateOHB_DT_FSM_State 都应在此处覆盖您的performDecision

【讨论】:

  • 你怎么知道这是问题所在?此处显示的 OP 代码不会尝试实例化这些类的对象。也许它们是抽象的
  • 你是对的,我想。我只是想,因为 OP 没有提供其他代码。
  • 在代码的最开头写着“// For force all the classes have this method”。
  • 好,所以你不想FSM_State实现这个方法?
【解决方案2】:

在定义类 FSM_state 的 CPP 文件中没有任何内容会触发 FSM_state&lt;eDECISION_TYPES, GameAI&gt; 的实例化 - 编译器没有理由构建一个,所以它没有。然后,当编译器到达 OHB_DT_FSM.hpp 中的那个实例化时——可能是在不同的编译单元中——它不再有权访问类定义,因此它无法构建那个实例化。

正如其他评论员所指出的那样——解决这个问题的一种方法是在使用模板类的任何地方都包含定义(不仅仅是声明)——通常是将定义放在标题中。这有其优点和缺点 - 现在对 FSM_state 内部的任何更改都意味着依赖于它的所有内容都必须重新编译。

另一种选择是在定义 FSM_state 的 CPP 文件中添加您知道需要的类型的 explicit instantiation

template class FSM_state<eDECISION_TYPES, GameAI>;

这实质上为编译器提供了为这些参数实例化模板类的提示,即使编译单元中没有其他东西需要该特定实例化。

【讨论】:

    猜你喜欢
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-18
    • 2014-03-13
    • 1970-01-01
    相关资源
    最近更新 更多