C++ 为什么在链接时出现多重定义错误?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9959563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why do I get a multiple definition error while linking?
提问by Burkhard
I use these two files hereand here.
I created a class in two separate files:
我在两个单独的文件中创建了一个类:
modul1.h
模块1.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
和 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):
现在我想在另一个文件(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:
当我使用以下 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 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
g++ main.o modul1.o -o main modul1.o:在函数中
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 ): 这里首先定义 modul1.o: 在函数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): 这里首先定义 collect2: ld 返回 1 退出状态
(At first I compiled it with code::blocks and got the same error)
(起初我用 code::blocks 编译它并得到同样的错误)
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
如何修改我的 Modul1 以免出现此链接错误?我不认为这很重要,但我正在使用一些带有 g++ 4.4.3 的 Ubuntu 64 位
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
采纳答案by bendervader
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
您构建它的方式,easylogger.h(以及因此easylogger-inl.h)被包含两次,一次用于modul1.h,一次用于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
在 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
and for modul1.cpp, include the real thing
对于 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!");
}
Good luck!
祝你好运!
回答by Rob?
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.
您在两个翻译单元中都包含“easylogger-impl.h”。easylogger-impl.h 中有函数定义。因此,您有多个函数定义。
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.
您可以通过将所有 easylogger-impl 函数标记为inline
或确保它们只出现在一个翻译单元中来解决这个问题。