为什么我会收到“多重定义”错误?我如何解决它?

时间:2017-01-11 18:06:14

标签: c++ g++ linker-errors

终端给出的

命令:

  

g ++ main.cpp test.cpp

错误讯息:

  

/tmp/ccvgRjlI.o:在函数`test2()'中:
test.cpp :(。text + 0x0):多个   `test2()'的定义   /tmp/ccGvwiUE.o:main.cpp:(.text+0x0):这里首先定义
  collect2:错误:ld返回1退出状态   main.cpp中

源代码:

#include "test.hpp"
int main(int argc, char *argv[])
{
    test2();
    return 0;
}

test.hpp

#ifndef _TEST_HPP_
#define _TEST_HPP_

#include <iostream>

void test();
void test2() { std::cerr << "test2" << std::endl; }

#endif

TEST.CPP

#include "test.hpp"

using std::cerr;
using std::endl;

void test() { cerr << "test" << endl; }

顺便说一下,下面的编译很好:

  

g ++ main.cpp

4 个答案:

答案 0 :(得分:1)

由于test.hppmain.cpp都包含test.cpp文件,因此test2函数有两种实现方式。因此链接器会产生错误。将函数实现移到test.cpp文件。

答案 1 :(得分:1)

您得到它是因为您在头文件中定义(实现)非静态和非内联函数test2,并在两个源文件中包含头文件。这意味着该函数将在translation units中定义。

答案 2 :(得分:1)

标题test.hpp包含在两个编译单元中。第一个是编译单元main.cpp,第二个是编译单元test.cpp

默认情况下,函数具有外部链接。这意味着具有相同名称和签名的函数在不同的编译单元中表示相同的功能。它们应定义一次。但是在程序中,函数test2的定义可以在两个编译单元中找到,链接器不知道要使用的函数的定义。

您可以将该函数声明为内联函数。例如

inline void test2() { std::cerr << "test2" << std::endl; }

在这种情况下,它可以在每个编译单元中定义。

或者您可以在标题中仅使用函数test放置函数声明,并在test.cpp中定义它。

另一种方法是将函数声明为具有内部链接。为此,您可以使用关键字static

在标题中定义函数
static void test2() { std::cerr << "test2" << std::endl; }

或将其放在未命名的名称空间

namespace
{
    void test2() { std::cerr << "test2" << std::endl; }
}

在这种情况下,每个编译单元都有自己的函数test2

答案 3 :(得分:0)

idPerson.clone()都包含Object.clone() 声明 main.cpp定义 test.cpp。通过在两个实现文件中包含test.hpp,您可以为每个定义和声明创建两个副本。您可以根据需要多次声明一个函数,但只能定义一次。将void test()的主体移动到单独的实现(.cpp)文件以解决链接器错误。