简体   繁体   English

C ++ #include标头

[英]C++ #include headers

there is a C++ book that says that we need to #include a header two times in two different files, one with a class, another with main() that uses the class from the previous file. 有一本C ++书说,我们需要在两个不同的文件中#include头两次,一个包含一个类,另一个包含使用上一个文件中的类的main()。

Here is the quote : 这是报价:

because our Sales_data class has a string member, Sales_data.h must #include the string header. 因为我们的Sales_data类具有字符串成员,所以Sales_data.h必须#include字符串标题。 Programs that use Sales_data also need to include the string header. 使用Sales_data的程序还需要包含字符串头。

But there is something I don't understand. 但是有些我不明白。 If we #include "Sales_data.h" in our main file, #include <(string)> is already in this header so no need to #include <(string)> in our main file. 如果我们在主文件中#include“ Sales_data.h”,则该头文件中已经包含#include <(string)>,因此无需在我们的主文件中#include <(string)>。

From what I understand, when we #include a file in a main file, C++ only copy and paste the entirety of the file called with the header in the main file. 据我了解,当我们在主文件中#include一个文件时,C ++只复制并粘贴带有头文件的整个文件。 So adding a second #include <(string)> is unnecessary. 因此,无需添加第二个#include <(string)>。 I'm talking about what happens when there isn't any #ifndef or #define in the header. 我说的是在标题中没有任何#ifndef或#define时会发生什么。

I did the test myself and I only needed to write #include <(string)> in one file and it worked. 我自己进行了测试,只需要在一个文件中编写#include <(string)>即可。 I isn't any # directive in either file except #pragma once in the header file. 除了头文件中的#pragma以外,我在任何一个文件中都没有任何#指令。

The description you read is bogus. 您阅读的描述是虚假的。 If the definition of a class C uses a type T, such as std::string , then that type needs to be available. 如果类C的定义使用类型T,例如std::string ,则该类型必须可用。 Usually (except with Microsoft code) the header that defines C includes the header that defines T. Client code of C then needs only include the header that defines C. 通常(除Microsoft代码外),定义C的标头包括定义T的标头。然后,C的客户端代码仅需要包含定义C的标头。

The situation is different with more arbitrary indirect header inclusions. 情况更多,间接标头包含更多内容。 Let's say class C doesn't use std::string , but its header includes <string> . 假设类C不使用std::string ,但是其标题包括<string> Then if your code that uses C, also uses std::string , it's good practice to let your code also include <string> . 然后,如果您使用C的代码也使用std::string ,那么最好让您的代码也包含<string> Even if that's not necessary at the current point of the code's evolution. 即使在代码发展的当前阶段这不是必需的。

The case for client code including the necessary headers, as with at least former Microsoft style, is that it by itself can give faster builds (fewer file accesses during a build), and supports some build optimization via primitive tools such as Visual C++'s precompiled headers, where all headers to be precompiled need to be collected in one big Mother Of All Headers. 至少与以前的Microsoft风格一样,客户端代码包括必要的标头的情况是,它本身可以提供更快的构建(在构建过程中减少文件访问),并通过基本工具(例如Visual C ++的预编译标头)支持某些构建优化。 ,需要将所有要预编译的标头收集在一个大的“所有标头之母”中。 The case against that practice is that it makes for more work in maintenance. 反对这种做法的理由是,这需要进行更多的维护工作。 And 80% of all programming is maintenance. 并且所有编程的80%是维护。

Consider the situation where Sales_data.h is modified to use a forward deceleration of std::string (instead of getting std::string 's deceleration from the system header.) This would allow Sales_data.c to compile with Sales_data.h , but would then cause compilation errors on any files including Sales_data.h , using std::string , but not including <string> . 考虑将Sales_data.h修改为使用std::string的正向减速(而不是从系统头获取std::string的减速)的情况。这将允许Sales_data.cSales_data.h一起编译,但是然后会使用std::string ,但不包括<string> ,对包括Sales_data.h在内的任何文件造成编译错误。

You are correct in assuming that you may get this header indirectly from other header files, but it is not something you should rely on. 假设您可以从其他头文件间接获取此头是正确的,但这不是您应该依靠的东西。 I believe the author is suggesting it as a best practice. 我相信作者建议将其作为最佳实践。

This sentence 这个句子

Programs that use Sales_data also need to include the string header. 使用Sales_data的程序还需要包含字符串头。

can be interpreted (with a grain of salt) as pointing out that any program that uses Sales_data does include the string header, because it is included in the Sales_data header. 可以解释为(指出一句话)指出使用Sales_data的任何程序都包含字符串标头,因为它包含在Sales_data标头中。

Of course a class should come with all required headers already included. 当然,一个类应该附带所有必需的标头。

The problem with the statement is that there are 2 distinct cases which should be distinguished, but the statement lumps them together. 该陈述的问题在于应区分两种不同的情况,但该陈述将它们混为一谈。

Case 1: 情况1:

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

Case 2: 情况2:

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

In the first case, the inclusion of <string> is an exposed implementation detail. 在第一种情况下,包含<string>是公开的实现细节。 The implementation could probably be changed to use a std::vector<char> instead. 可以将实现更改为使用std::vector<char>代替。 In the second case, std::string is part of the interface of class Foo , and no longer is an implementation detail. 在第二种情况下, std::stringclass Foo的接口的一部分,不再是实现细节。

In the second case, and only in the second case can you rely on <string> being included in "Foo.h" . 在第二种情况下,并且在第二种情况下,您可以依靠<string>包含在"Foo.h"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM