C ++ #include标头

时间:2017-01-04 00:57:42

标签: c++

有一本C ++书说我们需要在两个不同的文件中两次#include一个头文件,一个带有一个类,另一个带有main(),它使用上一个文件中的类。

这是引用:

  

因为我们的Sales_data类有一个字符串成员,所以Sales_data.h必须#include字符串头。使用Sales_data的程序也需要包含字符串标题。

但有一点我不明白。如果我们#include" Sales_data.h"在我们的主文件中,#include<(string)>已经在此标题中,因此无需#include<(string)>在我们的主文件中。

据我所知,当我们#include主文件中的文件时,C ++只会复制并粘贴主文件中带有标题的整个文件。所以添加第二个#include<(string)>没必要。我在谈论当标题中没有#ifndef或#define时会发生什么。

我自己做了测试,我只需要写#include<(string)>在一个文件中,它工作。我不是任何文件中的#指令,除了头文件中的#pragma一次。

4 个答案:

答案 0 :(得分:2)

您阅读的描述是虚假的。如果类C的定义使用类型T,例如std::string,那么该类型需要可用。通常(Microsoft代码除外)定义C的头包含定义T的头.C的客户端代码只需要包含定义C的头。

情况因更多任意间接头部包含而不同。假设C类不使用std::string,但其标题包含<string>。然后,如果您使用C的代码也使用std::string,那么最好让您的代码也包含<string>。即使在代码演变的当前阶段没有必要这样做。

客户端代码(包括必要的头文件,至少是以前的Microsoft风格)的情况是,它本身可以提供更快的构建(在构建期间更少的文件访问),并通过诸如Visual之类的原始工具支持一些构建优化C ++的预编译头文件,其中所有要预编译的头文件都需要收集在一个大的所有头文件中。反对这种做法的情况是它在维护方面做了更多的工作。 80%的编程都是维护。

答案 1 :(得分:0)

考虑将Sales_data.h修改为使用std::string的前向减速(而不是从系统标题中获得std::string减速度的情况。)这将允许{ {1}}使用Sales_data.c进行编译,但会使用Sales_data.h导致包括Sales_data.h在内的任何文件出现编译错误,但不包括std::string

你认为你可以从其他头文件间接获得这个标题是正确的,但它不是你应该依赖的东西。我相信作者建议将其作为最佳实践。

答案 2 :(得分:0)

这句话

  

使用Sales_data的程序也需要包含字符串标题。

可以解释(带有一点点盐),指出任何使用Sales_data的程序都包含字符串头,因为它包含在Sales_data头中。

当然,课程中应包含所有必需的标题。

答案 3 :(得分:0)

该陈述的问题在于应该区分2个不同的案例,但该陈述将它们混为一谈。

案例1:

// Foo.h
#include <string>
class Foo {
  std::string member;
public:
  Foo() { member = "Hello, world"; }
};

案例2:

// Foo.h
#include <string>
class Foo {
public:
  std::string Hi() const { return "Hello, world"; }
};

在第一种情况下,包含<string>是一个公开的实现细节。可能会将实现更改为使用std::vector<char>。在第二种情况下,std::stringclass Foo接口的一部分,不再是实现细节。

在第二种情况下,在第二种情况下,您可以依赖<string>中包含的"Foo.h"