可能重复:
Why can templates only be implemented in the header file?
我最近一直在尝试使用C ++。 目前我正在尝试编写一些我确定至少已经完成过一次的东西:一个简单的LinkedList类。 代码完成了,但我不知道怎么编译它。我一直在谷歌搜索,似乎我正在链接目标文件错误。这就是我的代码基本上是这样的:
TEST.CPP
#include "linkedlist.h"
int main()
{
LinkedList<int> list;
// do something
}
linkedlist.h
template <typename T>
class LinkedList
{
// a lot of function and variable definitions
}
然后有一个名为linkedlist.cpp的.cpp文件,其中包含LinkerList类的所有实际代码。尝试使用以下命令编译test.cpp时:
g++ ..\src\test.cpp
我被告知有'LinkedList :: LinkedList()'的未定义引用。所以我一直认为它被链接错误,因为有多个.cpp文件,所以我尝试了这样:
g++ -c -Wall -O2 ..\src\test.cpp
g++ -c -Wall -O2 ..\src\linkedlist.cpp
g++ -s test.o linkedlist.o
然而,这并没有改变任何事情。错误消息保持不变。 我一直试图在互联网上找到一些信息,然而,它并没有真正解决。
答案 0 :(得分:5)
您正在创建一个类模板,其中有一个重要的警告,即所有变量定义必须放在头文件中,以便在编译期间所有翻译单元都可以访问它们。
原因是模板的工作方式。在编译期间,编译器根据您的类模板定义实例化模板类。它不足以仅访问声明或签名:它需要提供整个定义。
将所有方法定义从.cpp
文件移到.h
文件中,一切都应该没问题(假设您实际上已经提供了默认构造函数的定义! )。
或者,您可以通过明确告诉编译器使用类似template class LinkedList<int>
之类的东西来实例化相应的模板类来解决这个问题,但在这种简单的情况下,这实际上并不是必需的。这包括头文件中的所有定义的主要优点是它可能减少代码膨胀并加速编译。但它可能根本没有必要,因为编译器在应用适当的优化方面变得更加聪明。
答案 1 :(得分:2)
您已将您的班级LinkedList
拆分,并将声明放在标题中,并将定义放在源文件中。 This does not work for a template。两者都必须在标题中。
答案 2 :(得分:1)
由于LinkedList
是模板,the definitions of its member functions ought to go in a header。
(严格来说,他们并不 ,但这是解决模板实例化复杂性的最简单方法,而不会完全违反包含惯例。)
哦,你还需要采用第二个构建方法;您应该将所有.cpp
文件链接在一起,或者使用-c
开关一次编译一个文件,然后将结果链接在一起。
答案 3 :(得分:1)
模板类就像是用于构造实际类的规则的定义。无论模板类是否实例化,编译器都会创建(实例化)实际的类。出于这个原因,模块类的所有代码必须在那时对编译器可见,这就是你必须在头文件中编写所有模板函数和方法的原因 - 因为你只包含cpp文件的头文件,只有头文件是可见的到那时的编译器。你没有将cpp文件包含在另一个cpp文件中,你永远不应该这样做。
如果我的理解是错误的,请纠正我。
P上。 S. C ++ 11是否解决了这个问题?
答案 4 :(得分:0)
对'LinkedList :: LinkedList()'
有一个未定义的引用
您是否检查过您的LinkedList类是否有构造函数?