对于我的CS Data Structures类,我正在使用链表实现通用堆栈。但是,我的.cpp文件中的所有构造函数和函数都出现了“重新定义....”错误。头文件“Stach.h”由教师给出,最后她包含了“Stack.cpp”。当我评论出那条线时,一切都很好,但她想要它。 有谁听说过这个?
谢谢你们,
大卫
答案 0 :(得分:2)
你的导师错了。您不在头文件中包含cpp
个文件。
编译器将在包含标头的任何位置处理它们。如果在文件中包含标头,则将为该翻译单元定义cpp
文件中实现的所有功能。如果将其包含在多个位置,则多个翻译单元将包含相同的符号,从而导致您提到的链接器错误。
如果你将实现声明为inline
,那么可行的方法是什么,但它仍然非常讨厌。
编辑:看到这些类是模板,我可以想到一个问题是你将它专门化为同一类型两次。我会从编译中删除cpp
文件,但是,如果可以,您应该将扩展名更改为impl
或其他内容。这样,编译器不会单独编译它,但它仍然可用于专门化您的类的文件。
答案 1 :(得分:1)
我唯一一次包含.cpp
文件的时候是我想将模板的实现放在.cpp
文件中,以便我的编辑器将其识别为C ++而不是C.堆栈的实现模板?
如果是,那么模板方法的实现必须可用于使用它们的编译单元。如果要在标题本身以外的位置实现,通常会将.ipp
或.tcc
用于模板实现文件。这就是Boost和许多其他库所做的事情。如果是这种情况,那么您不应该编译 stack.cpp ,因为当您的客户端或驱动程序包含头文件时,编译器会处理它。
答案 2 :(得分:0)
原因:在Stach.h文件中,使用#include指令包含Stach.cpp文件,该指令在预处理器中复制粘贴时Stach.h文件中的Stach.cpp代码
可能是您的CMakeLists.txt文件,在命令<< set(SOURCE_FILES ..)>>您还链接Stach.h和Stach.cpp文件。
因此,Stach.cpp的代码存在于Stach.h和Stach.cpp本身中,因此链接器会通知您存在重定义。
QuickFix:将Stach.cpp的文件名更改为Stach.anotherExtension(参见前面的评论:))
BestFix:从CMakeLists.txt删除Stach.cpp