2013-05-06 12 views
6

Sto creando un semplice file UTIL.h che contiene la funzione aplusb (int, int) per il mio progetto C++. Tuttavia non posso compilare e il messaggio di errore riguarda la definizione multipla di `aplusb (int, int) '. Potresti aiutarmi a correggere l'errore o darmi qualche suggerimento?Definizione multipla di un errore di funzione, anche quando si usano le clausole di guardia #if

Allego qui il mio progetto per il vostro riferimento di dettaglio.

util.h File

#ifndef UTIL_H_ 
#define UTIL_H_ 

int aplusb(int a, int b) { 
    return a + b; 
} 

#endif /* UTIL_H_ */ 

ClassA.h File

#ifndef CLASSA_H_ 
#define CLASSA_H_ 

class ClassA { 
public: 
    ClassA(); 
    virtual ~ClassA(); 
private: 
    int sum; 
}; 

#endif /* CLASSA_H_ */ 

File ClassA.cpp

#include "ClassA.h" 
#include "UTIL.h" 

ClassA::ClassA() { 
    // TODO Auto-generated constructor stub 
    sum = aplusb(3,5); 

} 

ClassA::~ClassA() { 
    // TODO Auto-generated destructor stub 
} 

ClassB.h File

#ifndef CLASSB_H_ 
#define CLASSB_H_ 

class ClassB { 
public: 
    ClassB(); 
    virtual ~ClassB(); 
private: 
    int sum; 
}; 

#endif /* CLASSB_H_ */ 

File ClassB.cpp

messaggio di errore
#include "ClassB.h" 
#include "UTIL.h" 

ClassB::ClassB() { 
    // TODO Auto-generated constructor stub 
    sum = aplusb(5,6); 
} 

ClassB::~ClassB() { 
    // TODO Auto-generated destructor stub 
} 

Compile

ClassB.o: In function `aplusb(int, int)': 
/home/vtvan/Desktop/workspace/commonfunc/UTIL.h:11: multiple definition of `aplusb(int, int)' 
ClassA.o:/home/vtvan/Desktop/workspace/commonfunc/UTIL.h:11: first defined here 
collect2: error: ld returned 1 exit status 
make: *** [commonfunc] Error 1 

risposta

17

prima variante - utilizzare inline specificatore

#ifndef UTIL_H_ 
#define UTIL_H_ 

inline int aplusb(int a, int b) { 
    return a + b; 
} 

#endif /* UTIL_H_ */ 

seconda variante - scrivere la definizione in .cpp file.

+0

Sono curioso di sapere perché la seconda variante sarebbe "giusta", e la prima no. Quali sarebbero i problemi nell'integrare questa funzione? – JBL

+0

@JBL davvero nulla, corretto. – ForEveR

+0

Grazie a tutti, posso correggere l'errore. – andycandy

0

I file di intestazione non sono pensati per avere funzioni effettive al loro interno (alcuni aspetti di C++ come i modelli non sono validi). La pratica generale nel tuo caso ti farebbe cambiare il tuo UTIL.H solo per prototipare la funzione (int aplusb(int a, int b);) e spostarne l'implementazione in un file sorgente.

+0

È perfettamente utile inserire le funzioni nei file di intestazione, a condizione che vengano contrassegnati in linea. – Stewart

+0

La mia affermazione _così come i modelli non resistenti_ non era intesa per essere esaustiva di tutti i casi in cui va bene mettere le funzioni nei file di intestazione. – mah

+0

Ma succede che i modelli non hanno nulla a che fare con il caso in esame, mentre esiste un modo perfettamente valido per definire questa funzione in un file di intestazione. – Gorpik

4

La funzione aplusb è stata creata nel file di inclusione. Ciò significa che per ogni file in cui lo includi, verrà creata una funzione pubblica aplusb, con conseguente conflitto di nomi.

Se la funzione deve essere in linea, contrassegnarla come segue. Se la funzione deve essere un modello, contrassegnarlo come tale. Se la funzione deve essere come l'hai scritta, inseriscila in un file cpp e mantieni il protoipo nel file h.

.h 
#ifndef UTIL_H_ 
#define UTIL_H_ 

int aplusb(int a, int b); 

#endif 

.cpp 
int aplusb(int a, int b) 
{ 
    return a+b; 
} 
2

È necessario dichiarare la funzione aplusb nel file di intestazione e fornire la definizione in un file cpp. Qualcosa di simile

util.h:

#ifndef UTIL_H_ 
#define UTIL_H_ 

int aplusb(int, int); 

#endif /* UTIL_H_ */ 

Il messaggio di errore che si sta dicendo che ogni volta che si include il file util.h, si sono ri-definire la funzione, che è esattamente quello che state facendo :-) Questa è una violazione dello ODR (one-definition-rule), che stabilisce che la definizione (di una funzione, in questo caso) deve essere univoca. Altrimenti il ​​compilatore non sarebbe in grado di scegliere tra le alternative (anche se, come in questo caso, sono uguali).

Si noti che i modelli complicano l'argomento un po '(in breve, perché un modello non è una definizione fino a quando non è istallato).

0

Si può anche creare una struttura Util dove ogni funzione è dichiarata statica. È quindi possibile accedere a ogni funzione utilizzando Util::<function name>

util.h File

#ifndef UTIL_H_ 
#define UTIL_H_ 

struct Util{ 
    static int aplusb(int a, int b) { 
     return a + b; 
    } 
}; 

#endif /* UTIL_H_ */ 

File ClassA.cpp

#include "ClassA.h" 
#include "UTIL.h" 

ClassA::ClassA() { 
    sum = Util::aplusb(3,5); 
} 

ClassA::~ClassA() { 
} 

File ClassB.cpp

#include "ClassB.h" 
#include "UTIL.h" 

ClassB::ClassB() { 
    sum = Util::aplusb(5,6); 
} 

ClassB::~ClassB() { 
} 
Problemi correlati