2011-09-04 102 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更合適。