2012-03-10 55 views
0

对于我的CS数据结构类,我使用链表实现了一个通用堆栈。但是,我正在为我的.cpp文件中的所有构造函数和函数获取“Redefinition of ....”错误。头文件“Stach.h”由教师给出,并在最后包含“Stack.cpp”。当我将该行注释掉时,一切正常,但她希望在那里。 有人听说过这个吗?在头文件中包含.cpp重定义错误 - 实现通用堆栈

谢谢你们,

大卫

+4

删除Stach.cpp包括源文件?很讨厌... – mfontanini 2012-03-10 20:56:13

+0

她给你任何构建指令吗? – moooeeeep 2012-03-10 21:00:57

+0

是的,让我们看看stack.cpp和stack.h。在头文件中包含一个.cpp文件是不寻常的,如果它打破了构建,我怀疑你和教授沟通不畅。 – 2012-03-10 21:07:46

回答

1

我只包含.cpp文件的唯一时间是当我想将一个模板的实现放在.cpp文件中,以便我的编辑器将其识别为C++而不是C时。堆栈的实现是模板吗?

如果是这样,则模板方法的实现必须可用于正在使用它们的编译单元。如果您打算在头文件本身以外的地方实施,通常使用.ipp.tcc代替模板。这是Boost和其他一些库所做的。如果是这种情况,那么你不应该编译stack.cpp,因为当你的客户机或驱动程序包含头文件时,编译器会处理这个问题。

+0

谢谢,就是这样,我使用的是xcode,因此它必须将所有内容编译在一起。我运行它使用终端只编译包含头文件的主,它工作正常。 – dajee 2012-03-10 21:15:27

2

你的教练是错误的。您不要在头文件中包含cpp文件。

编译器会在包含头文件的任何地方处理它们。如果将文件头包含在文件中,则会为该翻译单元定义在cpp文件中实施的所有功能。如果将它包含在多个位置,多个翻译单元将包含相同的符号,从而导致您提到的链接器错误。

如果您将实现声明为inline,但是它仍然非常讨厌,可以发挥什么作用。

编辑:看到如何类是模板,我可以想到一个问题是,你专门化它相同的类型两次。我会从编译中删除cpp文件,但如果可以的话,实际上应该将扩展名更改为impl或其他。这样,编译器就不会单独编译它,但它仍然可用于专门为您的课程设计的文件。

+0

考虑如何实现模板......通常是'.tcc'或'.ipp'文件而不是'.cpp'文件,但是相同的概念 – 2012-03-10 21:04:19

+0

@ D.Shawley它的概念并不完全相同。模板仅在专门化时才生成符号。 – 2012-03-10 21:06:01

+0

我见过有意义的例子。例如,假设你有一个需要使用的函数,它在.. \ foo \ foo.cpp中,但由于某种原因它不能被构建为一个.lib文件(例如,它只能构建为32位,而你需要64)。头文件foo.h可能只是“#include <.. \ foo \ foo.cpp>”而已。虽然这种情况很罕见,但这是一个完全合法的解决方案。 – 2012-03-10 21:06:27

0

原因:在Stach.h文件中,使用#include指令包含Stach.cpp文件,该文件在预处理器时间复制粘贴Stach.h文件中的Stach.cpp代码
可能是您的CMakeLists.txt文件,在命令< <设置(SOURCE_FILES ..)>>你也链接Stach.h和Stach.cpp文件。
因此,Stach.cpp的代码存在于Stach.h和Stach.cpp本身中,所以链接器会通知您存在重定义。
的QuickFix:Stach.cpp的更改文件名Stach.anotherExtension(见前面的评论:))
BestFix:从的CMakeLists.txt