从派生类调用父类的模板函数

时间:2016-05-04 11:44:30

标签: c++ templates inheritance crtp

我有一个非常具体的问题(不介意问我为什么要这样,解释它会非常复杂)

我想从父类调用模板函数,它间接调用子类的析构函数

我尝试实现此代码:

家长班:

template <typename BaseType>         //OpcUa_NodeInstance.h
class OpcUa_NodeInstance
{
public:
    template <typename BaseTypee, unsigned PrefixID>
    static void deleteType(unsigned int ObjID);

};

template <typename BaseType> // OpcUa_NodeInstance.cpp
template <typename BaseTypee, unsigned PrefixID>
void OpcUa_NodeInstance<BaseType>::deleteType(unsigned ObjID)
{
    if (ObjID == PrefixID)
    {
        NodeManagerRoot* pNodeManagerRoot = NodeManagerRoot::CreateRootNodeManager();
        auto dummyTypeInstance = new BaseTypee(UaNodeId(PrefixID, 2),
            UaString("Dummy_AutomationDomainType"), 2, pNodeManagerRoot);
        delete dummyTypeInstance;
    }
}

儿童班:

class AutomationDomainTypeBase: // AutomationDomainTypeBase.h
    public OpcUa_NodeInstance<AutomationDomainTypeBase>
{
   public:
          template <typename BaseType, unsigned int PrefixID> 
          static void deleteType(unsigned int ObjID);
}

问题是visual studio显示链接器错误

Error   5   error LNK2001: unresolved external symbol "public: static void __cdecl AutomationDomainTypeBase::deleteType<class AutomationDomainTypeBase,1018>(unsigned int)"

AutomationDomainTypeBase

我猜测编译器无法识别 deleteType 的实现已经在Parent-Class中。由于有超过400个子类,我正在寻找一种不在所有孩子中实现此功能的方法。

1 个答案:

答案 0 :(得分:1)

您正在尝试定义子类,而不包括父类的第一个定义。

如果我用两个定义编译你的代码,我没有编译错误。

但是如果我只编译子类定义,而不首先包含父类定义,那么我得到了:

1>Time\Time_Test.cpp(625): error C2504: 'OpcUa_NodeInstance' : classe de base non définie
1>Time\Time_Test.cpp(625): error C2143: erreur de syntaxe : absence de ',' avant '<'

就像你一样。

注意:确保在您定义OpcUa_NodeInstance<BaseType>::deleteType()模板类的头文件中正确定义OpcUa_NodeInstance模板成员函数(而不是仅声明)。否则,您将在链接时获得未定义的符号。

新编辑:

好的,我认为我得到了你需要的东西:如果你只想让AutomationDomainTypeBase::deleteType()用于任何子类,就不要声明/定义OpcUa_NodeInstance::deleteType()

另外,我认为你可以简单地定义OpcUa_NodeInstance::deleteType()如下:

template <typename BaseType>
class OpcUa_NodeInstance
{
public:
    template <unsigned PrefixID>
    static void deleteType(unsigned int ObjID);
};