2012-03-31 13 views
4

Ich verwende diese beiden Dateien here und here.Warum erhalte ich beim Verknüpfen einen Fehler mit mehreren Definitionen?

ich eine Klasse in zwei separaten Dateien erstellt:

modul1.h

#ifndef MODUL1_H 
#define MODUL1_H 

#include <iostream> 
#include <fstream> 

#include "easylogger.h" 

class Modul1 
{ 
    public: 
     Modul1(std::string name); 
    protected: 
    private: 
     easylogger::Logger *log; 
}; 

#endif // MODUL1_H 

und modul1.cpp

#include "modul1.h" 

Modul1::Modul1(std::string name):log(new easylogger::Logger(name)) 
{ 
    //ctor 
    //std::ofstream *f = new std::ofstream(name.c_str(), std::ios_base::app); 
    //log->Stream(*f); 
    //log->Level(easylogger::LEVEL_DEBUG); 
    //LOG_DEBUG(*log, "ctor ende!"); 
} 

Jetzt möchte ich in einer anderen Datei, diese Klasse verwenden (Haupt .cpp):

#include "modul1.h" 

int main() 
{ 
    std::cout << "Hello world!" << std::endl; 
    Modul1 mod1("test.log"); 
    return 0; 
} 

Wenn ich es mit dem folgenden Makefile kompilieren, erhalte ich eine „multiple Definition von ...“ Fehler:

g++ main.o modul1.o -o main modul1.o: In function easylogger::Logger::Format(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': modul1.cpp:(.text+0x0): multiple definition of easylogger::Logger::Format(std::basic_string, std::allocator > const&)' main.o:main.cpp:(.text+0x0): first defined here modul1.o: In function easylogger::Logger::WriteLog(easylogger::LogLevel, easylogger::Logger*, char const*, unsigned int, char const*, char const*)': modul1.cpp:(.text+0x2a): multiple definition of easylogger::Logger::WriteLog(easylogger::LogLevel, easylogger::Logger*, char const*, unsigned int, char const*, char const*)' main.o:main.cpp:(.text+0x2a): first defined here collect2: ld returned 1 exit status

(Zuerst habe ich es mit Code :: Blocks und bekam den gleichen Fehler kompiliert)

Wie kann ich mein Modul1 ändern, um diesen Verbindungsfehler nicht zu bekommen? Ich glaube nicht, es ist wichtig, aber ich bin mit etwas Ubuntu 64bit mit g ++ 4.4.3

Makefile:

CC=g++ 
CFLAGS=-c -Wall 

all: log_test 

log_test: main.o easylogger.h modul1.o 
    $(CC) main.o modul1.o -o main 

main.o: main.cpp modul1.h 
    $(CC) $(CFLAGS) main.cpp 

modul1.o: modul1.cpp modul1.h 
    $(CC) $(CFLAGS) modul1.cpp 
+5

Warum schreiben Sie eine ganze Seite, aber nicht die vollständige Fehlermeldung? –

+0

Mehrfache Definition von ... was? Das "Was" ist hier der wichtigste Teil. – Cornstalks

+2

Warum auch main.o reference modul1.cpp? – Cornstalks

Antwort

4

Die Art und Weise Sie diese bauen, easylogger.h (und folglich Easylogger-inl.h) wird

für main.cpp für modul1.h und einmal zweimal, einmal enthalten

davon Ihre Nutzung ist falsch. Aber Sie können dies tun, damit es funktioniert:

In modul1.h (Entfernen #include „easylogger.h“) und wie diese

#ifndef MODUL1_H 
#define MODUL1_H 

#include <iostream> 
#include <fstream> 
//#include "easylogger.h" 

namespace easylogger { class Logger; }; 

class Modul1 
{ 
    public: 
     Modul1(std::string name); 
    protected: 
    private: 
     easylogger::Logger *log; 
}; 

#endif // MODUL1_H 

und für modul1.cpp aussehen lassen, sind die wirkliche Ding

#include "modul1.h" 
#include "easylogger.h" 

Modul1::Modul1(std::string name):log(new easylogger::Logger(name)) 
{ 
    //ctor 
    //std::ofstream *f = new std::ofstream(name.c_str(), std::ios_base::app); 
    //log->Stream(*f); 
    //log->Level(easylogger::LEVEL_DEBUG); 
    //LOG_DEBUG(*log, "ctor ende!"); 
} 

Viel Glück!

+0

Schöne Workaround. Vielen Dank. – Burkhard

3

Sie umfassen „Easylogger-impl.h“ in Ihren beiden Übersetzungseinheiten. Es gibt Funktionsdefinitionen in easylogger-impl.h. Daher haben Sie mehrere Definitionen Ihrer Funktionen.

Die eine Definitionsregel besagt, dass Sie nur eine Definition eines Objekts oder einer Funktion haben müssen.

Sie können dieses Problem lösen, indem Sie alle Funktionen von easylogger-impl als inline markieren oder sicherstellen, dass sie nur in einer Übersetzungseinheit angezeigt werden.

+2

Ok, funktioniert die "fehlerhafte" Funktionen inline funktioniert, aber ich muss den Code von jemand anderem ändern. Wie würde ich sicherstellen, dass die easylogger-impl-Funktionen nur in einer Übersetzungseinheit angezeigt werden? – Burkhard

Verwandte Themen