对于我的CS Data Structures类,我正在使用链表实现一个Generic Stack。然而,我在.cpp文件中的所有构造函数和函数都出现了"重新定义…"错误。头文件"Stach.h"是由讲师给出的,最后她包含了"Stack.cpp"。当我注释掉那一行时,一切都很好,但她希望它在那里。有人听说过这个吗?
谢谢各位,
David
您的指导老师错了。头文件中不包含cpp
文件。
编译器将在包含标头的任何位置处理它们。如果在文件中包含头,则cpp
文件中实现的所有函数都将为该翻译单元定义。如果在多个位置包含它,多个翻译单元将包含相同的符号,从而导致您提到的链接器错误。
如果您将实现声明为inline
,则可能会起作用,但这仍然非常糟糕。
EDIT:看到类是如何成为模板的,我可以想到一个问题,那就是你把它专门化为同一类型两次。我会从编译中删除cpp
文件,不过,如果可以的话,实际上应该将扩展名更改为impl
或其他什么。这样,编译器不会单独编译它,但它仍然可以用于专门化类的文件。
我唯一一次包含.cpp
文件是当我想将模板的实现放在.cpp
文件中,以便我的编辑器将其识别为C++而不是C时。堆栈的实现是模板吗?
如果是,则模板方法的实现必须可用于使用它们的编译单元。如果要在头本身之外的其他地方实现,则通常将.ipp
或.tcc
用于模板实现文件。这就是Boost和许多其他库所做的。如果是这种情况,那么您不应该编译stack.cpp,因为当您的客户端或驱动程序包含头文件时,编译器会处理这一问题。
原因:在您的Stach.h文件中,您使用#include指令将Stach.cpp文件包括在内,该指令是在预处理器时间内复制粘贴Stach.cpp的代码到Stach.h文件中
可能是您的CMakeLists.txt文件,在命令<lt;设置(SOURCE_FILES...)>>还可以链接Stach.h和Stach.cpp文件
因此,Stach.cpp的代码存在于Stach.h和Stach.cpp本身中,因此链接器会通知您存在重新定义
QuickFix:将Stach.cpp的文件名更改为Stach.anotherExtension(请参阅前面的注释:))
最佳修复:从CMakeLists.txt 中删除Stach.cpp