【问题标题】:Why does this header compile with a missing #include?为什么这个头文件编译时缺少#include?
【发布时间】:2013-11-03 03:56:09
【问题描述】:

人.h

#ifndef PERSON_H_
#define PERSON_H_

/* Person.h */

class Person {
  int age;
  std::string name;

  public:
    Person(int, std::string);
    std::string getName();
    int getAge();

};

#endif /* PERSON_H_ */

person(int std::string) 函数声明使用 std::string 名称,但我没有将它包含在头文件中。因此,我希望编译器抱怨缺少符号。然而它编译并运行良好!为什么?

剩下的代码……

Person.cpp

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

Person::Person(int age, std::string name)
{
  this->name = name;
  this->age = age;
}

std::string Person::getName()
{
  return this->name;
}

int Person::getAge()
{
  return this->age;
}

Main.cpp

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

int main() {

  printFunc();

  Person chelsea_manning(5, std::string("Chelsea Manning"));

}

另外,我是 C++ 新手,所以如果您发现我的代码/OOP 有任何奇怪之处,请告诉我。

【问题讨论】:

  • 包含就像复制粘贴。看看将这些标头按顺序复制粘贴到您的 cpp 中会做什么。
  • 尝试从 main.cpp 和 person.cpp 中删除 #include &lt;string&gt; 看看会发生什么;)。
  • 尝试颠倒包含的顺序
  • 阅读 C 和 C++ 中的“翻译单元”。
  • 一般情况下,头文件应该写成自己编译。要对此进行测试,请编写一个只有 `#include "Person.h" 的简单 .cpp 文件并尝试编译它。

标签: c++


【解决方案1】:

程序的编译从包含main 函数的文件的顶部开始(从技术上讲,预处理器在程序编译之前运行,但它仍然在同一个位置开始)。在您的情况下,它所做的第一件事是将 &lt;string&gt; 包含到该文件中。然后它包括Person.h。由于&lt;string&gt; 已包含在内,因此字符串文件的所有内容都在代码中的人员文件之前,并且所有内容都以正确的顺序声明。如果您要在 &lt;string&gt; 之前包含 Person.h,或者在主文件中不包含 &lt;string&gt;,您确实会收到编译错误。

#include 方向的作用类似于复制/粘贴:它从字面上读取&lt;string&gt; 文件并将其内容放入包含它的源文件中。接下来,对Person.h 执行相同的操作。所以运行预处理器后的最终结果是

<-- contents of <string> -->
<-- contents of Person.h -->

int main()
...

因此,在您的示例中,所有内容都以正确的顺序声明。

【讨论】:

  • 更准确一点,编译不包含&lt;string&gt;,预处理包含。
  • @ChrisHayes 是的。解决了这个问题。
  • 在 Person.h 头文件中#include 是否是最佳实践?或者“复制”代码会很糟糕吗?同样,在 Person.cpp 中 #include 是否“不好”(它已经在 main 中定义)。换句话说,为什么不用 main 函数定义文件中的所有内容呢?我对何时、何地以及应该使用多少次#include 指令感到有些困惑。
  • 您可能会发现术语“翻译单元”很有用;它意味着预处理器完成后的整个源代码。 Person.h 标头的设计有缺陷;它不是独立的,因此不必要地难以使用。头文件应该是自包含的(这样它们就可以在不需要事先包含任何其他头文件的情况下使用)和幂等的(因此它们可以被包含两次,通过设计或更常见的方式是偶然地)而不会破坏编译。标头保护提供幂等性;包括#include &lt;string&gt; 将提供自我控制。
  • @jakeliquorblues:见Should I use #include in headers
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-04
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多