【问题标题】:Complicated error LNK2005: already defined C++复杂的错误 LNK2005:已定义 C++
【发布时间】:2009-04-06 19:56:45
【问题描述】:

在 Visual Studio 2008 中构建我的项目时,我收到 LNK2005: already defined in (...) 错误。我参考了其他相关问题,但如果没有其他问题,我的问题似乎有点复杂我正在处理的文件数量。

首先,我认为以 [current_file] ->includes_this_file 格式映射我在项目文件中的#include 语句对我很有帮助

我所有的头文件都用标准的#ifndef [Header] #define [Header] ... #endif 保护。

[调制器.h]

Modulator 类的原型

[ChorusUnit.h] ->Modulator.h

具有 Modulator 类型成员对象的 Chorus 类的原型

[AudioHandler.h] ->ChorusUnit.h

具有 Chorus 类成员对象的 AudioHandler 类的原型

[Chorus.cpp] ->AudioHandler.h

Modulator 和 Chorus 类成员的定义

[AudioHandler.cpp] ->Chorus.cpp

AudioHandler 类成员的定义

[ChorusUnit.cpp] ->AudioHandler.cpp

包含实际运行我的项目代码的 main() 函数的文件。

include 的顺序是因为在 Modulator.h、ChorusUnit.h 和 AudioHandler.h 中找到的类的所有函数定义都需要引用其他类的成员,所以我需要首先为所有类定义原型班级见面。

该错误特别指出在 Chorus.obj 文件中的 Chorus.cpp 和 AudioHandler.cpp 中找到的每个定义都已在 AudioHandler.obj 中定义。 还有另一组相同的错误类型,表示在 ChorusUnit.obj 文件中的 Chorus.cpp 和 AudioHandler.cpp 中找到的每个定义都已在 AudioHandler.obj 中定义。

可能有一个非常简单的解决方案,但我在一般链接方面并不是特别有经验(主要是 Java 程序员)。就我对该主题的有限知识而言,我只定义了一次所有内容,并且所有内容都只包含一次,所以我个人对为什么已经定义这些内容感到茫然。有的请赐教!

【问题讨论】:

    标签: c++ visual-studio-2008 linker


    【解决方案1】:

    错误可能是您在 AudioHandle.cpp 中说您 #include Chorus.cpp - 这可能不是您想要的。

    原因是,所有 .cpp 文件(除非您在 IDE 中做了一些特殊的事情)都是单独编译然后链接的。当您#include 另一个 .cpp 文件时,该文件的文本实际上是包含在内的;因此,包含文件中定义的所有对象也会出现在包含文件中。当你链接这两个文件时,共同的对象会导致冲突。

    【讨论】:

    • 我没有将#include [header] 放在.cpp 中,但仍然会出现链接问题!更重要的是,它为不再具有该类的文件中的类提供了错误。尝试将文件移动到新的解决方案仍然无法正常工作 T_T
    【解决方案2】:

    [AudioHandler.cpp] ->Chorus.cpp

    AudioHandler 类成员的定义

    这是错误的。包括 ChorusUnit.hpp 用于原型。

    【讨论】:

    • 所以我应该将 Chorus.cpp 重命名为 Chorus.hpp?我的项目中还没有同名的文件。
    • 那就是 ChorusUnit.h -- 包含 Chorus.cpp 中定义的函数原型的任何文件
    • 哦,好的。我觉得我明白了。当我包含头文件时,我不需要同时引用 .cpp 文件中的定义,因为编译器/链接器会自行执行此操作,因为我包含了头文件?
    • 没错。现在,我们能解决您的问题吗?
    【解决方案3】:

    AudioHandler.cpp 和 ChorusUnit.cpp 应该只 #include 头文件,而不是其他 C++ 源文件。

    预处理器将任何#included 文件的内容插入到#include 文件中,因此一旦开始链接,您就会从Chorus.cpp 中获得两个符号副本:一个来自编译Chorus.cpp,另一个来自编译AudioHandler.cpp (因为它#includes Chorus.cpp)。

    【讨论】:

      【解决方案4】:

      我不确定如何在 Windows 机器上执行此操作,但这些问题通常可以通过仅通过 C 预处理器运行代码来解决。这将导致合并的源文件实质上将所有“#include”语句替换为它们所引用的文件。如果您查看此组合文件,您会很明显地发现正在重新定义的内容。在 Linux/Unix 中,您可以使用 'cpp' 命令来执行此操作。

      【讨论】:

        猜你喜欢
        • 2010-10-11
        • 2012-04-25
        • 1970-01-01
        • 2022-01-13
        • 2015-08-10
        • 1970-01-01
        • 2014-12-21
        • 2012-08-04
        相关资源
        最近更新 更多