我有2个文件,即fun.cpp和main.cpp
fun.cpp
#include <iostream>
using namespace std;
void sum()
{
cout << "hello";
}
Main.cpp的
#include <cstdlib>
#include <iostream>
#include "fun.cpp"
using namespace std;
int main(int argc, char** argv) {
sum();
return 0;
}
当我在netbeans中运行上面的代码时,我得到了这个输出
"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory `/home/ravi/NetBeansProjects/ADBMS_v1.5'
"/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/Debug/GNU-Linux-x86/adbms_v1.5
make[2]: Entering directory `/home/ravi/NetBeansProjects/ADBMS_v1.5'
mkdir -p dist/Debug/GNU-Linux-x86
g++ -o dist/Debug/GNU-Linux-x86/adbms_v1.5 build/Debug/GNU-Linux-x86/fun.o build/Debug/GNU-Linux-x86/main.o
build/Debug/GNU-Linux-x86/main.o: In function `sum()':
/home/ravi/NetBeansProjects/ADBMS_v1.5/fun.cpp:5: multiple definition of `sum()'
build/Debug/GNU-Linux-x86/fun.o:/home/ravi/NetBeansProjects/ADBMS_v1.5/fun.cpp:5: first defined here
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/GNU-Linux-x86/adbms_v1.5] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
make[2]: Leaving directory `/home/ravi/NetBeansProjects/ADBMS_v1.5'
make[1]: Leaving directory `/home/ravi/NetBeansProjects/ADBMS_v1.5'
BUILD FAILED (exit value 2, total time: 150ms)
任何人都可以解释问题是什么吗?
提前致谢..
答案 0 :(得分:3)
不要在其他cpp文件中包含具有功能定义的cpp文件 这会导致相同功能的多个功能定义,并打破 One definition Rule。
将函数的声明放在头文件中,然后将该头文件包含在要使用该函数的任何源文件中。
<强> fun.h 强>
#ifndef HEADER_FUN_H
#define HEADER_FUN_H
void sum();
#endif //HEADER_FUN_H
<强> fun.cpp 强>
#include "fun.h"
#include <iostream>
using namespace std;
void sum()
{
cout << "hello";
}
<强> Main.cpp的强>
#include <cstdlib>
#include <iostream>
#include "fun.h"
using namespace std;
int main(int argc, char** argv)
{
sum();
return 0;
}
答案 1 :(得分:1)
每个.cpp
文件和.cpp
文件包含的所有文件都称为翻译单元。编译器分别编译每个翻译单元。然后,链接器将它们全部放在一个可执行文件中。
在编译器实际编译代码之前,它首先执行所有预处理语句,例如,#include
文件中的.cpp
语句。 #include
语句只是获取指定文件的内容,并将其“复制”到#include
语句所在的文件中。例如,fun.cpp
在预处理后可能如下所示:
/* the contents of the iostream file goes here */
using namespace std;
void sum()
{
cout << "hello";
}
对于Main.cpp
,类似这样的事情:
/* the contents of the cstdlib file goes here */
/* the contents of the iostream file goes here */
using namespace std;
void sum()
{
cout << "hello";
}
int main(int argc, char** argv)
{
sum();
return 0;
}
如您所见,fun.cpp
的内容已“插入”Main.cpp
。所以现在你有两个sum()
的定义,这违反了C ++中的一个定义规则(ODR)。由于编译器分别处理每个转换单元,因此在链接器看到您有两个不同的定义之后才会发现此错误,并且正确地抱怨结果。
由于sum()
函数非常简单,解决问题的一种方法是创建sum()
函数inline
,将fun.cpp
文件重命名为fun.h
},并将fun.h
包含在Main.cpp
中,而不是fun.cpp
。
// fun.h
#include <iostream>
inline void sum()
{
std::cout << "hello";
}
// main.cpp
#include <cstdlib>
#include <iostream>
#include "fun.h" // Note "fun.h"
int main(int argc, char** argv)
{
sum();
return 0;
}
对于更大的功能,或者如果要隐藏实现,Als' answer更合适。