问题
I use these two files here and here.
I created a class in two separate files:
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
and 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!");
}
Now I want to use this class in another file (main.cpp):
#include "modul1.h"
int main()
{
std::cout << "Hello world!" << std::endl;
Modul1 mod1("test.log");
return 0;
}
When I compile it with the following Makefile, I get a "multiple definition of..." error:
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 functioneasylogger::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
(At first I compiled it with code::blocks and got the same error)
How can I modify my Modul1 in order not to get this linking error? I don't think it is important, but I am using some Ubuntu 64bit with 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
回答1:
The way you are building this, easylogger.h (and consequently easylogger-inl.h) gets included twice, once for modul1.h and once for main.cpp
Your usage of it is wrong. But you can do this to make it work:
In modul1.h (remove #include "easylogger.h") and make it look like this
#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
and for modul1.cpp, include the real thing
#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!");
}
Good luck!
回答2:
You include "easylogger-impl.h" in both of your translation units. There are function definitions in easylogger-impl.h. Therefore, you have multiple definitions of your functions.
The one definition rule says that you must have one, and only one, definition of any object or function.
You may solve this problem either by marking all of the easylogger-impl functions as inline
, or by ensuring that they appear in only one translation unit.
来源:https://stackoverflow.com/questions/9959563/why-do-i-get-a-multiple-definition-error-while-linking