netbeans中的多重定义问题

时间:2011-09-04 12:32:26

标签: c++ netbeans

我有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)

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

提前致谢..

2 个答案:

答案 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更合适。