【问题标题】:Include .cpp file? [duplicate]包括 .cpp 文件? [复制]
【发布时间】:2012-02-08 20:20:50
【问题描述】:

可能重复:
Why can templates only be implemented in the header file?

我最近一直在尝试使用 C++。 目前我正在尝试编写一些我确信每个人都至少做过一次的事情:一个简单的 LinkedList 类。 代码已完成,但我不知何故无法编译它。我一直在谷歌搜索,似乎我将目标文件链接错了。我的代码基本上是这样的:

test.cpp

#include "linkedlist.h"

int main()
{
    LinkedList<int> list;
    // do something
}

链表.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

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

【问题讨论】:

  • 干得好,可以完整而连贯地制定这一点。 :) 对新人来说很少见,如今 :(
  • 由于LinkedList 是一个模板类,该类的用户需要所有方法的完整定义。一种方法是将所有方法内联在类中,而另一种方法是将方法放在单独的文件中并将它们包含在头文件中。
  • @Mike:很难称其为“重复”。这就是事情变得模糊的地方——问题是完全不同的,即使我们不需要再次涵盖相同的领域。 :)
  • @MikeSeymour:滑坡,那个。关于 SO 的大量答案可能对完全不相关的问题有好处!不过,我只是很难。
  • 正如我所说,在决定在这里提问之前,我一直在寻找答案。虽然它涵盖了同样的问题,但我不知道这可能是原因。可能是因为我在 g++ 之前用过 VS10,它在那里工作得很好。

标签: c++ templates linker


【解决方案1】:

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

原因在于模板的工作方式。在编译期间,编译器会根据您的类模板定义实例化模板类。仅访问声明或签名是不够的:它需要提供完整的定义。

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

或者,您可以通过明确告诉您的编译器使用template class LinkedList&lt;int&gt; 之类的东西来实例化适当的模板类来解决这个问题,但在这种简单的情况下,这确实不是必需的。与在头文件中包含所有定义相比,这样做的主要优点是它可能会减少代码膨胀并加快编译速度。但这可能根本没有必要,因为编译器在应用适当的优化方面变得更加聪明。

【讨论】:

  • export这个关键字已经不存在了,之前只是模糊支持。
【解决方案2】:

您已经拆分了您的班级LinkedList,并将声明放在标题中,并将定义放在源文件中。 This does not work for a template。两者都必须在标题中。

【讨论】:

  • 他确实说过Then there's a .cpp file called linkedlist.cpp which contains all the actual code of the LinkerList class.
  • 这就是我通过略读问题得到的结果 - 已修复。
  • 原谅你提出这样的问题 ;)
【解决方案3】:

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

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

P。 S。 C++11 解决了这个问题吗?

【讨论】:

  • P.S.不,不,它没有。 C++03 尝试过但失败了,所以 C++11 放弃了,实际上移除了尝试。
【解决方案4】:

由于LinkedList 是一个类模板the definitions of its member functions ought to go in a header

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

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

【讨论】:

    【解决方案5】:

    有一个未定义的对 'LinkedList::LinkedList()' 的引用

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-05
      • 2012-02-12
      • 1970-01-01
      • 2020-09-27
      • 2015-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多