【问题标题】:template class, implementation code causing linking issues模板类,实现代码导致链接问题
【发布时间】:2009-09-14 13:14:50
【问题描述】:

我目前有一个程序,其中我的主要代码位于文件 main.cpp 中。 Main.cpp 包含一个头文件“class.h”,它声明了一个在 main.cpp 中使用的类。

在 main.cpp 中我也有声明我在 main.cpp 中使用的函数的函数声明。 这些函数的代码位于单独的 .cpp 文件 fucntions.cpp 中。 与 main.cpp 一样,functions.cpp 也包含 class.h,因为类类型在函数中使用。

class.h 仅包含类声明。 class.h 的实现代码在单独的 .cpp 文件 classimplementation.cpp 中。

在我尝试将 class.h 中的类设为模板类之前,一切正常。 然后我得到链接问题。研究和测试表明,这是因为模板类函数的定义需要与声明一起驻留在 class.h 中。

因此,我从 classimplementations.cpp 中取出所需的代码并将其放入 class.h。 这确实解决了我最初的链接问题,但我得到了更多的链接错误,这些错误似乎告诉我我正在尝试重新定义我移至 class.h 的函数。

我认为这是因为 class.h 被 main.cpp 调用,又被 functions.cpp 调用。 因此 class.h 中的函数被定义了两次:

错误 41 错误 LNK2005: "public: __thiscall RecordPocket::RecordPocket(int)" (??0?$RecordPocket@VT@@@@QAE@H@Z) 已在 classimplementation.obj functions.obj 中定义

我知道类实现代码确实应该被排除在包含文件之外,但由于模板类限制必须将类函数保持在本地,我似乎(在我的新手心目中)别无选择。

有没有人遇到过这种情况并且可以提供任何建议。 我尝试使用标准 ifndef CLASSIMP、#define CLASSIMP 代码和 PRAGMA ONCE 来围绕我从 classimplementation.cpp 移动到 class.h 的功能,但两者都没有任何区别。

如果所有其他方法都失败了,我会将函数从 functions.cpp 移到 main.cpp 中,以便 class.h 只被调用一次,但我宁愿找出我做错了什么,因为我确信它会再次发生。

【问题讨论】:

  • 可以在 class.h 中发布一些关于您的代码的示例代码吗?
  • 认为在这里发布一些代码会很有用;您的问题应该很容易解决,但有点难以识别。

标签: c++ class templates linker


【解决方案1】:

您可以将模板函数保留在模板中 class what{/HERE/};

template<typename T>
class MyTempClass{
     void myFunctions{
      // code here
     }
 }

已编辑:我删除了 Glen 更正的代码

【讨论】:

  • inline 关键字不是必需的。
  • 如果你在类声明之外声明方法,你需要内联以避免重新定义
  • s/声明方法/定义方法/
  • @Arkaitz Jimenez,不,你不知道。试试看
  • @Glen,你说得对,它不需要,我猜有 2 个被实例化了,一个被编译器删除了
【解决方案2】:

我认为您的问题围绕这些问题展开。正如您所暗示的那样,任何模板函数定义(即模板类的成员函数的模板函数)都需要在 .h 文件中完全表达,因为当编译器找到模板的特定实例时,它需要构建函数。 您发现了这一点并将一些实现移到了您的 class.h 文件中。现在,如果链接器在多个模块中发现 MyFunction() 则只是丢弃其中一个,则报告无链接器错误。

但是,您不能在两个不同的模块中定义相同的非模板函数,因为这会产生上述错误。所以我怀疑您还将一些非模板功能移到了 .h 文件中;因此将其包含在两个单独的 obj 文件中并生成链接器错误。您引用的错误消息支持这一理论,因为我注意到 __thiscall RecordPocket::RecordPocket(int) 似乎不是模板。

【讨论】:

    猜你喜欢
    • 2010-12-11
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 2017-08-29
    • 2013-01-03
    相关资源
    最近更新 更多