2013-07-16 33 views
0

我有3個類,每個類與其他相關,其中3個使用相同的函數,所以我決定創建functions.h文件,我將「外部」函數放在每個人使用。所以對於示範

通過在多個類中使用外部函數來獲取錯誤

functions.h 
len function 
subs function 
A.cpp 
    #include "functions.h" 
    #include "A.h" 
    #include "B.h" 
    cout<<len(word); 
B.cpp 
    #include "functions.h" 
    #include "B.h" 
    #include "A.h" 
    cout<<subs(word,0,1); 
C.cpp 
    cout<<len(word); 

所有的人包括與特定功能functions.h文件,頭文件我真的使用頭文件保護。
當我建立的項目,我得到的錯誤:

Error 1 error LNK2005: "int __cdecl len(char *)" ([email protected]@[email protected]) already defined in A.obj C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\1033\Ass3\Ass3\B.obj Ass3 

同樣的錯誤是潛艇(功能)。
有什麼建議爲什麼會發生?
謝謝!


編輯:
functions.h

#ifndef FUNCTIONS_H 
#define FUNCTIONS_H 
#include <math.h> 

    int len(char *w){ 
    int count=0; 
    int i=0; 
    while (w[i]!='\0') 
     { 
      count++; 
      i++; 
     } 
//cout<<"Length of word is:"<<count<<"\n"; 
    return count; 

} 
    char *subs(char *w,int s,int e){ 
    int i,j=0; 
    int size=0; 

    size=abs((e))+1; 
    //cout<<"new size is:"<<size<<"\n"; 
    char *newW=new char[size]; 


    for(i = 0 ;i<e; i++) 
     { 

      newW[i]=w[s]; 
      s++; 

     } 

    newW[i]='\0'; 
    return newW; 

    } 

    #endif 

Word.cpp

#include "Word.h" 
#include "functions.h" 

Word::Word(char *_word){word=_word;} 
bool Word::equals(char* _word){ 
    cout<<"len of the first word is: "<<len(word)<<" and len of the checked word is: "<<len(_word)<<endl; 
    if(len(word)!=len(_word)) 
     return false; 
    else{ 
    for(int i=0;i<len(word);i++) 
     if(word[i]!=_word[i]) 
      return false; 
    } 
    return true; 

} 
char Word::getWord(){ 
    char *nW = new char[len(word)]; 
    //cout<<"len of word is:"<<len(word); 
    int l=len(word); 
    for(int i=0;i<l;i++) 
     { 
      nW[i]=word[i]; 
      cout<<nW[i]; 
    } 

    return *nW; 

} 
void Word::print(char *word){cout<<word;} 
void Word::print(){cout<<word<<" ";} 

Sentence.cpp

#include "Sentence.h" 
#include "Word.h" 
#include "functions.h" 
Sentence::Sentence() 
{ 

    char* sentence=new char[300]; 
    cout<<"Entere sentence"<<endl; 
    cin.getline(sentence,300); 
    int i,j=0,lastIndex=0,count=0; 


    int l=len(sentence); 
    cout<<"Size of sentence is: "<<l<<"\n"; 

    for(i=0;i<l;i++){ 
     //' ' ,'.', ',', '?', ':', '!' ,'\N','\r' ',', '\t', ',', '-' 
     if (sentence[i]==' '|| 
      sentence[i]=='.'|| 
      sentence[i]==','|| 
      sentence[i]=='?'|| 
      sentence[i]==':'|| 
      sentence[i]=='!'|| 
      sentence[i]==';'|| 

      sentence[i]=='-'){ 
      count++; 
      if(count==1) 
       { 
        //cout<<subs(sentence,0,i); 
       //cout<<"Start Index: 0 and Length is: "<<i<<"\n"; 
       words[j]=new Word(subs(sentence,0,i)); 



        lastIndex=i; 

        j++; 
       } 
      else{ 


     //cout<<subs(sentence,lastIndex+1,i-lastIndex-1); 
       //cout<<"Start Index: "<<lastIndex+1<<" and Length is: "<<i-lastIndex-1<<"\n"; 
      words[j]=new Word(subs(sentence,lastIndex+1,i-lastIndex-1)); 

      lastIndex=i; 
      j++; 
      } 
     } 

    } 


    if(lastIndex==0){ 
     //cout<<subs(sentence,0,l); 

     words[j]= new Word(subs(sentence,0,l)); 
    } 
    else{ 
     //cout<<subs(sentence,lastIndex+1,i); 
     //cout<<"Start Index: "<<lastIndex+1<<" and length is: "<<i-lastIndex-1<<"\n"; 
     words[j]= new Word(subs(sentence,lastIndex+1,i-lastIndex-1)); 

    } 
    wordNum=count+1; 

} 
bool Sentence::containsWord(char* _word){ 

    for(int i=0;i<200;i++){ 


     if(words[i]->equals(_word)) 
       return true; 

    } 
    return false; 

} 

int Sentence::getWordNum(char *_word){ 

    for(int i=0;i<200;i++){ 
     cout<<words[i]->getWord(); 
     if(words[i]->equals(_word)) 
       return i+1; 

    } 
    return -1; 

} 
int Sentence::getWords(){return wordNum;} 
int Word::getLen(){ 

    return len(word); 
} 
+2

你能用真實的代碼展示一個最簡單的例子嗎? – juanchopanza

+0

@juanchopanza我加了。 –

+0

你爲什麼要在Sentence.cpp中定義Word :: getLen()? –

回答

4

好像你已經把功能實現分成functions.h。將原型留在那裏並將實現移至單獨的文件,如functions.cpp

這應該做的伎倆。

更新更多關於你得到的錯誤的解釋。

當您使用#include它將被處理器編譯前處理(認爲它像內聯.h文件到源文件)。這個過程發生在每個編譯單元中,我的文件是.cpp(認爲它像樹的根)。

現在,由於有樹的「根」是不同的(A.cppB.cpp,...)包括後衛不會幫助你避免被聯到每一個編譯單元函數實現

這會導致鏈接錯誤,因爲這些函數有多個實現。

+0

好吧,得到它,主要問題是在我實現functions.h我沒有做到這一點,所以當我編寫oop程序我需要這樣做,在功能編程錯誤不會出現。 –

+0

@OfirAttia它不是關於OOP和功能的。這與C/C++以及涉及構建過程的步驟密切相關。例如,Java是面向對象的,但這裏沒有這樣的問題。 –

+0

問題也在C中顯示。請參閱我的回答,以獲得完整的問題解答。當然,它與OOP /函數式編程(在C接受) –

2

每個編譯單元(即A.cpp,B.cpp和C.cpp)都包含在functions.h中的每個函數的定義。

包括守衛對此沒有幫助,因爲他們只是碰巧在編輯單位邊界內有效果(即,如果直接或間接包含functions.h兩次,例如A。CPP)

可能的解決方案是:

  1. functions.h聲明的功能,並在單獨的編譯單元定義它們,說functions.cpp(這是你的榜樣要走的路)
  2. 你使每一位功能functions.h模板函數(只能這樣做是否有意義)
  3. 你聲明的每一個功能functions.h是靜態的(這只是一種變通方法,我絕不建議你做所以!!!)

P.S.關於第3點。這可能是有道理的,所以你可能想知道什麼是static。當提及一個自由函數時,static關鍵字將此函數標記爲編譯單元的本地函數。因此,該函數將不會在鏈接表中導出,並且不會從另一個編譯單元中調用。這就是「技巧」起作用的原因,因爲你仍然有多個定義,它們對每個編譯單元都是「私有的」,並且不存在任何可能的衝突。當你使用不是「接口」一部分的自由函數時,這是特別有用的,它只是本地幫助函數。

+0

謝謝,它幫助我瞭解一些事情。 –

相關問題