【问题标题】:Calling Template-Function of Parent-Class from Derived Class从派生类调用父类的模板函数
【发布时间】:2016-05-04 11:44:29
【问题描述】:

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

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

我尝试实现这段代码:

父类:

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 的实现已经在父类中。由于有超过 400 个子类,我正在寻找一种不在所有子类中实现此功能的方法。

【问题讨论】:

  • 您提供的代码在我看来确实编译得很好,使用 ms vc14。
  • @shrike 谢谢,我忘了包含 Parent.h,我编辑了我的主题。你能帮我解决链接器错误吗?
  • template &lt;typename BaseType&gt; template &lt;typename BaseTypee 是这里的输入错误还是您的代码输入错误?首先是 Type,然后是 Typee。
  • @bipll 如果我将类模板和函数模板命名为相同,我会收到此错误:c3860
  • 哦,当然,这两个是不同的类型变量。

标签: c++ templates inheritance crtp


【解决方案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&lt;BaseType&gt;::deleteType() 模板成员函数在您定义OpcUa_NodeInstance 模板类的头文件中正确定义(并且不是仅声明)。否则,您将在链接时得到一个未定义的符号。


新编辑:

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

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

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

【讨论】:

  • 谢谢,我忘了包含 Parent.h,我编辑了我的主题。你能帮我解决链接器错误吗?
  • @Pepelee:看我回答中最后的“注”,你会得到答案; OpcUa_NodeInstance&lt;BaseType&gt;::deleteType() 的实现也必须在头文件中实现。
  • 但我已经在头文件中实现了它,正如您在我的主题开头(第一个 sn-p)中看到的那样
  • :-) 问题是关于继承这种模板函数,我为 crtp 做了研究,但找不到答案..
  • @Pepelee:CRTP 看起来正确;问题是模板成员函数只在子类头中声明,没有定义/实现;如果通用实现是可能的,则在子类头中添加此模板成员函数的实现(就像父类模板成员函数一样)。否则,您可能必须实现一些专业化......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多