2011-09-04 74 views
0

多重定义的我有2个文件,即fun.cpp和main.cpp中问题在NetBeans

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) 

任何人都可以解释什么问题?

在此先感谢..

回答

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

每个文件和.cpp文件包含的所有文件称为一个翻译单元。编译器分别编译每个翻译单元。链接器然后将它们放在一个可执行文件中。

在编译器实际编译代码之前,它首先执行所有预处理语句,例如.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.hMain.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更合适。