用于采购功能的头文件和包含

Header files and include for sourcing functions

我是 C++ 的新手,来自一种解释型语言,我在理解头文件与库和依赖关系的关系时遇到了一些困难。

例如,假设我有我的项目主体:

#include <vector>

//----------------------------define some auxiliary function which deals with vectors
void A(std::vector<int> &vect)
{ 
    vect.clear();
}

//----------------------------main body
int main()
{
    std::vector<int> vect = {1,2,3}
    A(vect);
    return 0 ;
}

现在假设我想在一个单独的 .cpp 文件中定义辅助函数 A(),并且仍然能够从我的主 .cpp 文件中调用它。我的问题是-对于这个项目,我是否必须 #include <vector> 在所有使用该库中的东西的 .cpp 文件中?如果是这样,我还需要在我的 main 文件中 #include <vector> 吗?

我想我明白头文件是如何工作的,但仍然不清楚如果我有多个文件使用同一个库中的元素会发生什么。

只是使用矢量组件的文件需要包含它。您还可以在包含另一个文件时包含一个组件。

例如:

  1. Example.h
#include <vector>

//----------------------------define some auxiliary function which deals with vectors
void A(std::vector<int> &vect) { 
    vect.clear();
}
  1. Example.cp
include "Example.h"

//----------------------------main body
int main() {
    std::vector<int> vect = {1,2,3};
    A(vect);
    return 0;
}

来自@Vivick 的评论

您通常也会 #include <vector> 在 main 中以避免需要查找哪个头文件包含哪个库。

您不必包含在所有 .cpp 文件中。如果你在你的 Example.h 或 Example.cpp 中#include 并且你只在你的主文件中包含其中一个,比如 #include "Example.h" 或 "Example.cpp",你可以在你的 main 中也使用向量。

假设您创建了 a.h 和 a.cpp a.h

#pragma once //ensure a.h will only be included once in case multiple c++ include it
#include <vector>
void A(std::vector<int> &vect)

a.cpp

#include "a.h" // include your own declarations
void A(std::vector<int> &vect)
{
...
}

任何包含 a.h 的人都会附带 <vector> 但每个模块 (.h) 仍然需要包含所有自己的依赖项(即如果您需要 std::vector 某处,您必须包含它,否则如果在其他上下文中使用,您的代码可能无法再编译。

包含是可传递的。 #include foo.h 只是将 foo.h 的内容替换为 include-directive.

这是正确的,但不好:

// foo.h
#include <vector>
std::vector<int> v;

// bar.h 
#include "foo.h"

// main.cpp
#include "bar.h"   
std::vector<int> x;
int main() {}

这将编译,但它是非常糟糕的风格。你应该包括你使用的东西。如果有人只看 foo.h,假设他们意识到不再需要 v,他们会看到没有使用 vector,删除 #include <vector> 并由此中断 main.cpp。您无法查看包含 foo.h 的所有文件来决定是否需要包含。

这是正确且更好的:

// foo.h
#include <vector>
std::vector<int> v;

// bar.h 
#include "foo.h"

// main.cpp
#include "bar.h"   
#include <vector>
std::vector<int> x;
int main() {}

一些人建议最后包含标准库 headers。这样,如果 foo.h 忘记包含 <vector>,您将得到一个错误。有时 headers 不需要类型的完整定义,而只需要声明。在这种情况下,可以使用前向声明来减少编译时间。然后仅通过包含 header 在源中提供定义。示例:

// foo.h
struct bar;   // forward declaration 
struct foo {
    bar* p;   // pointer, need only declaration, no definition!
    void do_something();
}

// foo.cpp
#include "bar.h"
void foo::do_something() {
    bar b;      // create instance, needs definition
    // ...
}

PS:您不必担心过于频繁地包含 header。 Headers 通过所谓的包含守卫防止多次包含:

// moo.h
#ifndef MOO_HEADER_INCLUDE_GUARD
#define MOO_HEADER_INCLUDE_GUARD

// the actual contents

#endif

如果在一个翻译单元中相同的 header 被包含两次,预处理器(包含由预处理器处理)将看到符号 MOO_HEADER_INCLUDE_GUARD 已经定义并跳过header.