有一本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一次。
答案 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::string
是class Foo
接口的一部分,不再是实现细节。
在第二种情况下,在第二种情况下仅,您可以依赖<string>
中包含的"Foo.h"
。