简单程序中的链接器错误:函数的多重定义

linker error in simple program: multiple definition of function

本文关键字:函数 定义 程序 链接 简单 错误      更新时间:2023-10-16

我的函数test被添加到两个不同的.cpp-文件中,这些函数对它们各自的文件是私有的,如下所示

test1.cpp

#include <iostream>
using namespace std;
void test()
{
    cout << "test" << endl;
}

test2.cpp

#include <iostream>
using namespace std;
void test()
{
    cout << "test" << endl;
}

main.cpp

#include <iostream>
using namespace std;

int main()
{
    return 0;
}

在链接过程中,我得到了错误multiple definition of test(),但考虑到这两个文件有自己的私有作用域,这怎么可能呢!?如果我在每个.cpp-文件的相应头中包含函数原型,我可以理解,但在这个例子中没有这样的东西。

您需要inline关键字:

inline void test()
{
    cout << "test" << endl;
}

这允许您在不同的源文件中有多个定义,而不会违反一个定义规则。但是,请注意,该函数仍然具有外部链接,并且它们都将解析到同一地址。还有:

应在每个翻译单元中定义内联函数,其中它是odr使用的,在每个案例

如果需要具有不同地址的单独函数(内部链接),请改用static关键字。

两个测试函数都在程序的同一全局命名空间中。为了避免错误,您可以:1) 将任意一个或两个函数包装在名称空间中:

namespace A
{
void test()
{
   ...
}
}

2) 使用static关键字3) 只需将其中一个重命名为

在每个test函数中添加static

#include <iostream>
using namespace std;
static
void test()
{
    cout << "test" << endl;
}

详细说明以上答案:

在C++中,函数声明可以根据需要重复多次。然而,函数定义(即函数体)只能出现一次。

在创建二进制文件时,编译器会将每个文件编译为一个obj文件,因此在您的示例中,您最终会得到test1.obj、test2.obj和main.obj。所有文件成功编译后,链接器会将它们链接在一起以创建可执行文件。这就是找到同一函数的多个定义的地方,也是链接失败的原因。

根据您的需要,您可以执行以下操作来解决此问题:

  • 如果您想要多个不同的函数具有相同的名称,那么您必须消除它们的歧义。如果你只有一种方法:,C++就不会是C++

    1. 旧的c方法:使用static关键字
    2. 使用匿名命名空间
    3. 使用命名空间
  • 如果你只想要一个功能:

    1. 将定义与声明分离,即将声明放在头文件中,然后将定义移动到源文件中
    2. 将函数定义为页眉中的内联函数