从头文件中定义方法时的c ++链接器错误[重复]

Posted

技术标签:

【中文标题】从头文件中定义方法时的c ++链接器错误[重复]【英文标题】:c++ linker error when method is defined out of header file [duplicate] 【发布时间】:2011-10-01 14:22:54 【问题描述】:

可能重复:Where to define C++ class member template function and functors that instantiate it?inclusion of header files in case of templates

我正在使用类模板。我的班级中有几种方法,如果我在 .cpp 文件中定义它们,我会收到链接器错误

error LNK2019: unresolved external symbol

模板类中的所有方法都需要在头文件中定义吗?它让我的代码看起来很糟糕,但如果这是我能接受的唯一方法。

【问题讨论】:

是的。想一想:如果你在myClass.cpp 中定义了myClass<T>::foo(),在bar.cpp 中定义了一些其他代码调用myClass<int>::foo(),那么该函数将不会在.o 文件中定义。 【参考方案1】:

模板类中的所有方法都需要在头文件中定义吗?

是的。但是您仍然可以将不依赖模板参数的部分分解出来,并将它们作为普通函数或作为 mixin 类放入常规模块中:

class NonTemplatedOpsMixin

    int bar();  // defined elsewhere
;

template <typename T>
class TemplatedStuff : private NonTemplatedOpsMixin

    T foo(T &x)  x += bar(); 
;

【讨论】:

也许值得一提的是外部模板?【参考方案2】:

模板类中的所有方法都需要在头文件中定义吗?

是的:编译器要实例化模板方法定义,它必须具有可用的方法体。

这让我的代码看起来很糟糕

一种常见的技术是在标题中使用单独的部分:

template <typename T> class Foo 
  int Method();
;

// Other classes ...

// Now supply implementation details, not relevant to users of the class
template <typename T> int Foo<T>::Method()

  // implementation


// Other implementations

另一种技术是将正文移动到单独的头文件中,例如foo-inl.h#include "foo-inl.h" 来自 foo.h

【讨论】:

【参考方案3】:

模板类中的所有方法都需要在头文件中定义吗?

是的

这让我的代码看起来很糟糕,但如果这是我能接受的唯一方法。

在这种情况下,您可以将 .cpp 文件包含在标头中:

//filename.h

template<typename T>
class whatever

     //...
;

#include "filename.cpp"  //write this at the bottom of filename.h

这相当于在标头本身中提供所有 模板 定义,但实际上您有两个文件。

好吧,正如评论所说,构建系统可能对扩展名.cpp 不满意,在这种情况下,您可以选择.h(或.hpp)。现在安全了。

【讨论】:

构建系统可能对包含在另一个文件中的.cpp 不满意;我会为此使用detail/filename.hpp

以上是关于从头文件中定义方法时的c ++链接器错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章

未定义对向量<String> g++ 链接器错误的引用[重复]

使用 Hexagon DSP 工具链的多定义链接器错误

C 文件中的 C++ 文件中的链接器错误调用函数

Makefile:链接器错误[重复]

STM32 Eclipse + ARM GNU 工具链错误链接器

gcc:在 C++ 应用程序中链接 C 库会导致“多重定义”错误