包括.cpp文件

Include .cpp file?

本文关键字:文件 cpp 包括      更新时间:2023-10-16

可能重复:
为什么模板只能在头文件中实现?

我最近一直在试用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++ ..srctest.cpp

我被告知有一个未定义的对"LinkedList::LinkedList()"的引用。所以我一直认为它链接错误,因为有多个.cpp文件,所以我这样尝试:

g++ -c -Wall -O2 ..srctest.cpp
g++ -c -Wall -O2 ..srclinkedlist.cpp
g++ -s test.o linkedlist.o

然而,这并没有改变任何事情。错误消息保持不变。我一直试图在互联网上找到一些信息,但并没有真正奏效。

您正在创建一个类模板,其中有一个重要的警告,即所有变量定义都必须放在头文件中,以便在编译期间所有翻译单元都可以访问它们。

原因是模板的工作方式。在编译过程中,编译器会根据类模板定义实例化模板类。仅仅访问声明或签名是不够的:它需要整个定义可用。

将所有方法定义从.cpp文件移到.h文件中,一切都会好起来(假设您实际上已经为默认构造函数提供了定义!)。

或者,您可以通过显式地告诉编译器使用template class LinkedList<int>之类的东西实例化适当的模板类来绕过这一点,但在这种简单的情况下,这确实没有必要。与在头文件中包含所有定义相比,这种方法的主要优势在于,它可能会减少代码膨胀并加快编译速度。但这可能根本没有必要,因为编译器在应用适当的优化方面已经变得更加聪明了。

您已经拆分了类LinkedList,并将声明放在头中,将定义放在源文件中。这对模板不起作用。两者都必须在标题中。

Template类就像是一个规则的定义,用来构造一个实际的类。只要存在模板类的实例化,编译器就会创建(实例化)实际的类。由于这个原因,模板类的所有代码在这一点上必须对编译器可见,这就是为什么必须在头文件中编写所有模板函数和方法的原因——因为你只包括cpp文件的头,所以在那一点上只有头对编译器可见。您不会将cpp文件包含到另一个cpp文件中,而且永远不应该这样做。

如果我的理解有误,请纠正我。

第页。SC++11是否解决了这个问题?

由于LinkedList是一个类模板,其成员函数的定义应该放在一个标头中。

(严格来说,它们没有,但这是绕过模板实例化复杂性的最简单方法,而不会完全偏离包含约定。)

哦,无论如何,你都需要采取第二次构建方法;您应该将所有.cpp文件链接在一起,或者使用-c开关一次编译一个文件,然后稍后将结果链接在一起。

存在对"LinkedList::LinkedList()"的未定义引用

您检查过LinkedList类是否有构造函数吗?