2012-03-31 65 views
4

我用這兩個文件herehere爲什麼鏈接時會出現多重定義錯誤?

我創建了一個類中兩個單獨的文件:

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 

和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!"); 
} 

現在我想在另一個文件中使用這個類(主.cpp):

#include "modul1.h" 

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

當我用下面的Makefile編譯它,我得到一個「的多個定義...」錯誤:

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

(起初我與代碼::塊編譯,並得到了同樣的錯誤)

如何修改我的Modul1以免出現鏈接錯誤?我不認爲這是很重要的,但我使用Ubuntu的一些與64位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

爲什麼寫一整頁,但沒有發佈完整的錯誤信息? – 2012-03-31 20:47:54

+0

多重定義...什麼?這裏的「什麼」是最重要的部分。 – Cornstalks 2012-03-31 20:51:50

+2

另外,爲什麼main.o引用modul1.cpp? – Cornstalks 2012-03-31 20:52:58

回答

4

要構建這個,easylogger.h(因此easylogger-inl.h)的方式被包含了兩次,一次爲modul1.h和一次main.cpp中

你對它的用法是錯誤的。但你可以做到這一點,使其工作:

在modul1.h(刪除的#include「easylogger.h」),使它看起來像這樣

#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 

和modul1.cpp,包括真正的事情

#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!"); 
} 

祝你好運!

+0

很好的解決方法。謝謝。 – Burkhard 2012-03-31 22:35:46

3

你有「easylogger-impl.h」在這兩個你的翻譯單位。 easylogger-impl.h中有函數定義。因此,您有多個函數定義。

的一個定義規則說,你必須有一個且只有一個,任何對象或函數的定義。

您可以通過將所有的easylogger-impl函數標記爲inline或確保它們僅出現在一個翻譯單元中來解決此問題。

+2

好的,使內聯的「錯誤」函數可以工作,但我必須修改其他人的代碼。我如何確保easylogger-impl函數僅出現在一個翻譯單元中? – Burkhard 2012-03-31 21:26:52