为什么在链接时出现多重定义错误?

新手上路,请多包涵

在这里这里 使用这两个文件。

我在两个单独的文件中创建了一个类:

模块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

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

现在我想在另一个文件(main.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:在功能 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 个退出状态

(起初我用 code::blocks 编译它并得到同样的错误)

如何修改我的 Modul1 以免出现此链接错误?我认为这并不重要,但我正在使用一些带有 g++ 4.4.3 的 Ubuntu 64 位

生成文件:

 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

原文由 Burkhard 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

您构建这个的方式,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!");
}

祝你好运!

原文由 bendervader 发布,翻译遵循 CC BY-SA 3.0 许可协议

您在两个翻译单元中都包含“easylogger-impl.h”。 easylogger-impl.h 中有函数定义。因此,您有多个函数定义。

单一定义规则说您必须对任何对象或函数有一个且只有一个定义。

您可以通过将所有 easylogger-impl 函数标记为 inline 或确保它们仅出现在一个翻译单元中来解决此问题。

原文由 Robᵩ 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题