【问题标题】:Why is Visual Studio giving a duplicate error even though I'm not explicitly including a source file?为什么即使我没有明确包含源文件,Visual Studio 也会出现重复错误?
【发布时间】:2020-03-30 14:48:30
【问题描述】:

我正在使用 Visual Studio 2019。我创建了一个新的 C++ 控制台应用程序。我的 Source Files 文件夹中有一个 Main.cpp 文件,代码如下:

#include <iostream>

int i = 10;

int main()
{
    std::cout << i << std::endl;
    std::cin.get();
}

我在我的 Source Files 文件夹中创建了第二个名为 File2.cpp 的文件,其中只有以下行:

int i = 2;

如果我尝试编译此代码,我会收到错误消息“找到一个或多个多重定义的符号”。为什么即使我没有在 Main.cpp 中明确完成#include "File2.cpp",我也会收到此错误?

更新: 但是,如果我删除 File2.cpp 并将其替换为我的 Header Files 文件夹中名为 File2.h 的文件(仅包含一行:int i = 2),以及所有其他在相同的情况下,它编译得很好。与前面的例子类似,唯一的区别是第二个文件不是 .cpp 源文件,而是一个 .h 头文件。

【问题讨论】:

  • 编译 Main.cpp 时,它定义了一个全局变量int i。编译 File2.cpp 时,它定义了一个全局变量int i。当两个生成的目标代码文件链接在一起(以及一些使您的程序运行的实现启动代码)时,链接器会遇到 two i's。简而言之,这是一个链接时间的事情,由编译时间的事情产生,由于编码决策的事情......这就是你进入画面的地方。

标签: c++ include


【解决方案1】:

在 C++ 中,全局变量(在任何类之外声明)默认具有外部链接。也就是说,当应用程序链接时,它们对其他模块是可见的。

因此,两个 .cpp 文件都向链接器公开了一个变量 i,它是对象。

四种解决方案:

1) 将一个或两个声明放在不同的命名空间中:

namespace Wibble
{
    int i = 2;
}

因此它们具有不同的完全限定名称。

2) 声明一个或两个为static

static int i = 2;

关闭外部链接。

3) 将一个或两个放在匿名命名空间中:

namespace
{
    int i = 2;
}

它会自动为每个命名空间分配一个唯一的命名空间——实际上与 (2) 的结果相同

4) 将除其中一个之外的所有声明为extern 而不进行初始化:

extern int i;

这表示变量 i 实际上与另一个文件中的变量相同,但没有声明为 extern

【讨论】:

    【解决方案2】:

    首先,您永远不想包含 cpp 文件。构造代码的一般方法1 是将声明放在一个或多个头文件中,然后为每个头文件创建一个 cpp 文件。然后编译并链接所有这些 cpp 文件。

    这就是 Visual Studio 自动为您做的事情。您在项目中创建所有头文件和 cpp 文件,然后它将编译每个 cpp 文件,然后将生成的目标文件链接在一起以构建可执行文件。所以,因为Main.cppFile2.cpp 都定义了相同的变量,所以你会得到一个多重定义错误,因为这两个文件是一起编译的。

    1:unless you have templates

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多