包括.cpp文件
我读过像这里这样的地方,你必须包括.h文件,而不是.cpp文件,否则,你会得到一个错误。 所以例如
main.cpp中
#include <iostream> #include "foop.h" int main(int argc, char *argv[]) { int x=42; std::cout << x <<std::endl; std::cout << foo(x) << std::endl; return 0; }
foop.h
#ifndef FOOP_H #define FOOP_H int foo(int a); #endif
foop.cpp
int foo(int a){ return ++a; }
工作,但如果我用#include "foop.h"
replace#include "foop.cpp"
我得到一个错误(使用Dev C ++ 4.9.9.2,Windows):
multiple definition of foo(int) first defined here
为什么是这样?
其中include
从文件(这是<>
或<>
的参数)复制所有内容,所以当预处理程序完成其工作时, main.cpp
将如下所示:
// iostream stuff int foo(int a){ return ++a; } int main(int argc, char *argv[]) { int x=42; std::cout << x <<std::endl; std::cout << foo(x) << std::endl; return 0; }
所以foo会在main.cpp
中定义,但foop.cpp
也存在一个定义,所以编译器由于函数重复而“变得困惑”。
阻止包含.cpp文件的原因有很多,但不是严格禁止的。 你的例子应该编译好。
问题可能是你正在编译main.cpp和foop.cpp,这意味着两个foop.cpp副本被链接在一起。 链接器抱怨重复。
这归结为定义和声明之间的区别。
- 您可以多次声明函数和variables,使用不同的翻译单位,也可以使用相同的翻译单位。 一旦你声明了一个函数或一个variables,你可以从这一点使用它。
- 您可以在所有翻译单元中只定义一次非静态函数或variables。 多次定义非静态项会导致链接器错误。
标题通常包含声明; cpp文件包含定义。 如果多次包含定义文件,则会在链接过程中重复。
在你的情况下,一个定义来自foo.cpp
,另一个定义来自main.cpp
,其中包括foo.cpp
。
注意:如果您将foo
更改为static
,则不会有链接错误。 尽pipe没有错误,但这不是一件好事。
当你说#include "foop.cpp"
,就好像你已经复制了foop.cpp
的全部内容并将其粘贴到main.cpp
。
所以当你编译main.cpp
,编译器会发出一个main.obj
,它包含两个函数的可执行代码: main
和foo
。
编译foop.cpp
本身时,编译器会发出一个foop.obj
,其中包含函数foo
的可执行代码。
当你将它们连接在一起时,编译器会看到foo
函数的两个定义(一个来自main.obj
,另一个来自foop.obj
),并且抱怨你有多个定义。
因为你的程序现在包含foo
函数的两个副本,一个在foo.cpp中,一个在main.cpp中
把#include看作是编译器的指令,将该文件的内容复制/粘贴到你的代码中,所以你最终会得到一个处理过的main.cpp,看起来像这样
#include <iostream> // actually you'll get the contents of the iostream header here, but I'm not going to include it! int foo(int a){ return ++a; } int main(int argc, char *argv[]) { int x=42; std::cout << x <<std::endl; std::cout << foo(x) << std::endl; return 0; }
和foo.cpp
int foo(int a){ return ++a; }
因此多重定义错误
你应该只包含头文件。
如果包含头文件,头文件会自动find.cpp文件。 – >这个过程是由LINKER完成的。
由于一个定义规则 (可能是1 )。
在C ++中,每个非内联对象和函数在程序中必须有一个定义。 通过#include
定义foo(int)
的文件(CPP文件),它在foop.cpp为#include
d的每个文件中以及在foop.cpp本身中定义(假设foop.cpp被编译) 。
你可以使一个函数inline
来覆盖这种行为,但我不build议在这里。 我从来没有见过这样的情况: #include
一个CPP文件是必要的,甚至是不可取的。
在某些情况下,可能需要包括一些事物的定义。 当您尝试从声明中分离模板的定义时,这是特别正确的。 在这些情况下,我将文件命名为HPP而不是CPP来表示不同之处。
1 :“(可能)”我可能在这里说,因为你发布的实际代码应该编译没有错误,但考虑到编译器错误,您发布的代码似乎可能与您正在编译的代码不完全相同 。
使用“.h”方法更好但是如果你真的想包含.cpp文件,那么在foo.cpp中使foo(int)是静态的