如果在.h文件中包含某些内容,您是否必须再次包含相同的内容?

时间:2017-09-01 22:22:11

标签: c++ c intellij-idea

所以我只是想知道你是否在例如header.h文件中#include something

例如,这称为header.h

#include <vector>
#include <iostream>
#include <somethingElse>

所以,例如,如果我创建一个名为something.cpp的文件,我是否需要再次放入所有这些包含语句?

#include "header.h"
// If I include #header.h in this file. Do the #include carry over to this file. Or do they not

我很想知道,因为每当我在.h文件中包含<vector>内容时,我之前在#include文件中使用的.h语句总是变为灰色,这意味着它们不会被使用。是因为我在.h文件中使用过它吗?它不是问题或任何我只是好奇的东西。

2 个答案:

答案 0 :(得分:4)

您不需要再次包含这些标题,因为您的编译器可以找到这些标题,您可以尝试阅读并理解makefile (or CMakeList) ,这将有所帮助

答案 1 :(得分:2)

请务必使用inclusion guard#pragma once来避免“多个文件包含”,以防止包含多个文件。

包含文件意味着文件的内容将添加到您编写的地方。

以下是一个例子:

// header.h
const int vlaue = 10;
const int value2 = 0;

// main.cpp

#include "header.h"
#include "header.h"

在“header.h”的内容之上添加两次到main.cpp。

你知道结果是什么吗?这是一个编译时错误,抱怨重新定义valuevalue2

在上面的例子中,我认为绿色程序员不会被它困住,但它只是一个解释,所以我所说的是一个庞大的程序,其中许多头文件和许多源文件和一些文件包含其他文件然后它跟踪正确的文件包含会非常困难。

使用inclusion guardspragma once的解决方法,例如:

让我们将header.h修改为:

// header.h

#ifndef MY_HEADER_H
#define MY_HEADER_H

const int vlaue  = 10;
const int value2 = 0;

#endif

现在在main.cpp中:

#include "header.h"
#include "header.h"
#include "header.h"

上面的代码工作正常,没有重复的标题内容添加到main.cpp。你知道为什么吗?这就是Macro的神奇之处。因此,预处理器首次检查是否已经使用名称MY_HEADER_H定义了宏,并且第一次确定它未定义,因此添加了内容。第二个等等条件失败,因为已经定义了宏,因此header.h的内容不会被添加到调用它的位置。

包含守卫的缺点是,如果你有一个与包含守卫同名的宏,那么它已经被定义,所以内容永远不会被添加(空内容)。因此,您会收到编译时错误:

value, `value2` undeclared identifiers.

第二种解决方案是使用pragma,例如:

让我们修改header.h文件:

// header.h
#pragma once

const int vlaue = 10;
const int value2 = 0;

// main.cpp

#include "header.h"
#include "header.h"

上面的代码正常工作,所以没有多次包含header.h这是因为pragma once的魔力:这是一个非标准但广泛支持的预处理器指令,旨在使当前源文件仅在一次编辑中包含一次。因此,#pragma曾经提供与包含保护相同的目的,但有几个优点,包括:更少的代码,避免名称冲突,有时提高编译速度。

  • 最后,您应该在其内容使用的位置包含标题,例如:

    // Shape.h
    
    class Shape{
        // some code here
    };
    
    // Cube.h
    
    #include "Shape.h"
    
    class Cube : public Shape{
         // some code here
    };
    
    // Cuboid.h
    
    // #include "Shape.h" 
    #include "Cube.h" // So here the Shape.h is added to Cube.h and Cube.h is added here.
    
    class Cuboid : public Cube{
       // some code here
    };
    
  • 如上所示,Shape.h的内容间接添加到Cuboid.h中,因为它被添加到Cube.h中,cuboid.h包含Cube.h,因此它被添加到它中。因此,如果您在一个源文件中包含两个标题,则不会包含一次保护或编译指示,那么您将获得重复的内容。