为什么链接时出现多重定义错误
Why do I get a multiple definition error while linking?
我在这里和这里使用这两个文件。
我在两个独立的文件中创建了一个类:
模块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
和module1.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!");
}
现在我想在另一个文件(main.cpp)中使用这个类:
#include "modul1.h"
int main()
{
std::cout << "Hello world!" << std::endl;
Modul1 mod1("test.log");
return 0;
}
当我用下面的Makefile编译它时;多重定义"错误:
g++main.o模1.o-o主
modul1.o:在函数easylogger::Logger::Format(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
:
中modul1.cpp:(.text+0x0):的多重定义easylogger::Logger::Format(std::basic_string<char, std::char_traits<char>, std::allocator<char> > 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):的多重定义easylogger::Logger::WriteLog(easylogger::LogLevel, easylogger::Logger*, char const*, unsigned int, char const*, char const*)
main.o:main.cpp:(.text+0x2a):首先在此处定义
collect2:ld返回1退出状态
(一开始我用代码::blocks编译它,得到了相同的错误)
如何修改我的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
按照您构建它的方式,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!");
}
祝你好运!
您在两个翻译单元中都包含"easylogger impl.h"。easylogger impl.h中有函数定义。因此,您有多个函数定义。
一个定义规则规定,任何对象或函数都必须有一个,而且只有一个定义。
您可以通过将所有easylogger impl函数标记为inline
,或者确保它们只出现在一个翻译单元中来解决此问题。
这不是针对您的特定案例的解决方案,但我会向其他找到此主题的人提及,因为它可能会产生相同的错误。
如果您正在运行编译器,并且省略了-o
标志,并且您的二进制文件的副本已经存在,则编译器将尝试将新的对象文件与该二进制文件链接。新的对象文件和二进制文件都将有自己的main
和各种其他符号,并向您发出警告。
> g++ MyTest.cxx -g MyTest -I.
/usr/bin/ld: MyTest: in function `main':
/t/proj/MyTest/MyTest.cxx:172: multiple definition of `main'; /tmp/cccYfx2V.o:/t/proj/MyTest/MyTest.cxx:172: first defined here
:
:
:
collect2: error: ld returned 1 exit status
> g++ MyTest.cxx -g -o MyTest -I.
>
请注意,第二个命令具有-o
选项,并且在没有注释的情况下成功。
- 使用命名空间时出现多个定义错误
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 尝试调用 .h 文件中定义的变量时出现变量未定义错误
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 链接阶段出现多重定义错误
- 避免模板类中的重定义错误
- 即使我没有包含多个文件,C++中的多个定义错误
- 跨多个类的全局变量而不会出现重定义错误?
- 尝试运行 wasm 函数时出现模块未定义错误
- C++ 预期的左大括号以及重定义错误
- C++:成员的越界声明必须是纯虚函数的定义错误
- c++中数组的未定义错误
- Visual C:模板类中的自定义错误消息
- 为什么C++模板不会导致多个定义错误?
- 只有一个定义/声明时标头声明变量的多堆定义错误
- C++ 在多个其他类中使用单个类 - 编译时出现多个定义错误
- 基类未定义.错误 C2504
- Q 斯坦达项重定义错误
- 可视化C++中的结构定义错误
- VC++ C2011 重定义错误 - 未使用的头文件