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

时间:2013-06-28 10:09:16

标签: c++ linker linker-errors

我的函数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 - 文件'对应的标题中包含函数原型,我就能理解它,但在这个例子中没有这样的东西。

4 个答案:

答案 0 :(得分:2)

您需要inline关键字:

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

这允许您在单独的源文件中具有多个定义,而不违反单定义规则。但请注意,该功能仍然具有外部链接,并且它们都将解析为相同的地址。也:

  

应在每个翻译单元中定义内联函数   它是使用过的,并且每个都有完全相同的定义   情况下

如果您想要具有不同地址的单独功能(内部链接),请改用static关键字。

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

在每个static函数中添加test

#include <iostream>

using namespace std;

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

答案 3 :(得分:1)

详细说明上述答案:

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

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

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

  • 如果您想要多个具有相同名称的不同功能,则必须消除它们的歧义。如果你只有一种方法可以做到这一点,C ++就不会是C ++:

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

    1. 将定义与声明分开,即将声明放在头文件中并将定义移动到源文件中。
    2. 将函数定义为标题中的内联