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

新手上路,请多包涵

终端给出的命令:

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;
}

测试.hpp

 #ifndef _TEST_HPP_
#define _TEST_HPP_

#include <iostream>

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

#endif

测试.cpp

 #include "test.hpp"

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

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

顺便说一句,以下编译得很好:

g++ main.cpp

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

阅读 1.2k
2 个回答

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

默认情况下,函数具有外部链接。这意味着具有相同名称和签名的函数在不同的编译单元中表示相同的函数。它们应定义一次。但是,在您的程序中,函数 test2 的定义存在于两个编译单元中,并且链接器不知道要使用该函数的什么定义。

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

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

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

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

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

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

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

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

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

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

你得到它是因为你在头文件中定义(实现)了非静态和非内联函数 test2 ,并且在两个源文件中都包含了头文件。这意味着该函数将在两个 翻译单元 中定义。

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

推荐问题