0

我的函数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-files 的相应标题中,我可以理解它,但在这个示例中没有这样的东西。

4

4 回答 4

4

您需要inline关键字:

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

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

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

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

于 2013-06-28T10:18:10.993 回答
1

要详细说明上述答案:

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

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

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

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

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

    1. 将定义与声明分开,即将声明放在头文件中,并将定义移到源文件中。
    2. 在标题中将函数定义为内联
于 2013-06-28T11:39:19.530 回答
1

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

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

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

于 2013-06-28T10:19:03.237 回答
1

添加static每个test功能。

#include <iostream>

using namespace std;

static
void test()
{
    cout << "test" << endl;
}
于 2013-06-28T10:20:39.987 回答