【问题标题】:Multiple definition error when compiling C++ code in CodeBlocks在 CodeBlocks 中编译 C++ 代码时出现多重定义错误
【发布时间】:2013-01-10 05:35:04
【问题描述】:

我在一个可能非常微不足道的问题上被困了好几个小时。

这是类的最基本用法。

头文件:person.h

class person
{
  protected:
    std::string _Name;
  public:
    void setName(std::string);
};

实现:person.cpp

#include <string>
#include "person.h"

void person::setName(std::string name)
{
  _Name = name;
}

驱动程序:main.cpp

#include <iostream>
#include "person.cpp"

int main()
{
  std::cout << "Yes, it worked.\n";
  return 0;
}

尝试在 CodeBlocks 中编译此代码(使用 GNU GCC)时,我收到一个错误:

~\person.cpp|5|multiple definition of `person::setName(std::string)'|
~\person.cpp|5|first defined here|
||=== Build finished: 2 errors, 0 warnings (0 minutes, 0 seconds) ===|

我在头文件中有一个原型,在实现文件中有正文。多重定义在哪里?如果我在 person.cpp 中的 'void' 之前添加 'inline' 就可以了,但是在这种情况下我为什么要这样做呢?

此外,当在 cmd 中编译与“g++ main.cpp -o main.exe”相同的代码时,它可以完美运行(没有内联)!

【问题讨论】:

  • 不包含 cpp 文件。链接它们。除此之外,您的标题应该有一个包含保护。

标签: c++ compiler-errors codeblocks


【解决方案1】:

您不需要在 main.cpp 中包含 *.cpp 文件。您需要包含*.h 文件。

简而言之 - *.cpp 文件包含实现并由编译器编译。 *.h 文件包含定义并且可以包含在 *.cpp 文件中。当你包含*.cpp 文件时,你会得到同一个对象的多个定义。

另外,你需要添加包含保护

#ifndef MY_HEADER
#define MY_HEADER
... code of your header file ...
#endif

或者只是添加

#pragma once

如果你的编译器支持的话。

【讨论】:

  • #pragma once 不是标准的。
  • 它无处不在。 VC++、GCC、Clang 和 Digital Mars 支持该指令。
  • 谢谢!将 main.cpp 的第 2 行从 #include "person.cpp" 更改为 #include "person.h" 使其工作。但现在我有点困惑。我将头文件包含在 main.cpp 中。头文件没有引用(我可以看到)实现头文件中声明的 .cpp 文件。为什么我没有收到错误消息?这是在幕后做的吗?
  • @user1960469 编译器编译两个独立的翻译单元 - main.cpp 和 person.cpp。第一个包含函数main 的定义,第二个包含setName 的定义。在您的特定示例中,main.cpp 不直接包含person 的实现并不重要,因为您没有使用它。优化编译器将简单地忽略 person.h 的内容。但是,如果您实际使用该代码,则链接器将结合两个翻译单元的输出,以便定义可用于您的最终二进制文件。
【解决方案2】:

今天发生了这种情况。

当使用 file - new 等在代码块中添加文件时,会出现一个屏幕询问您是否要将文件包含在调试和发布版本中。您通过勾选方框无辜地回答“是”。结果是该文件被自动包含在内,当您自己明确包含它时,您最终会复制。所以,不要勾选那些框。

干杯 波奇

【讨论】:

    【解决方案3】:

    您可以在代码块中的另一个 .cpp 中包含一个 .cpp 文件。但不要将其添加到您创建的项目中。如果文件包含在项目中,代码块将尝试像这样编译它:

    g++ main.cpp -o main.o

    g++ person.cpp -o person.o

    然后使用这两个 .o 文件创建最终输出文件。由于main.cpp包含func.cpp,会遇到多重声明错误。

    现在,如果您只保留项目中的 main.cpp 文件,则只会编译该文件,并且不会出现相同的错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多