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

C++ 如果在.h文件中包含某些内容,是否必须再次包含相同的内容?,c++,c,intellij-idea,C++,C,Intellij Idea,所以我只是想知道您是否在例如header.h文件中包含了一些内容: // header.h #pragma once const int vlaue = 10; const int value2 = 0; // main.cpp #include "header.h" #include "header.h" 例如,这被称为header.h: #include <vector> #include <iostream> #include <somethingEl

所以我只是想知道您是否在例如header.h文件中包含了一些内容:

// header.h
#pragma once

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

// main.cpp

#include "header.h"
#include "header.h"
例如,这被称为
header.h

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

我很好奇,因为每当我在.h文件中包含
内容时,我以前在
.h
文件中使用的
\include
语句总是变灰,这意味着它们没有被使用。是因为我在
.h
文件中使用了它吗?这不是一个问题或任何事情,我只是好奇

您不需要再次包含这些头,因为编译器可以找到这些头。您还可以尝试阅读和理解,这将有所帮助。

始终尝试通过使用
包含保护
#pragma一次来避免“多文件包含”,以防止多文件包含

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

下面是一个例子:

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

// main.cpp

#include "header.h"
#include "header.h"
上面,“header.h”的内容两次添加到main.cpp

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

在上面的例子中,我认为绿色程序员不会被它困住,但这只是一个解释,所以我要说的是,当一个巨大的程序中有许多头文件、许多源文件和一些文件包含其他文件时,那么跟踪正确的文件包含将非常困难

使用
包含保护
pragma一次的解决方法,例如:

让我们修改
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中没有添加重复的标题内容。你知道为什么吗?这就是宏的魔力所在。因此,在第一次预处理器检查宏是否已使用名称
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曾经起到与include-guard相同的作用,但有几个优点,包括:代码更少,避免名称冲突,有时还可以提高编译速度

  • 最后,在使用其内容的地方,应包括标题,例如:

    // 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,所以它被添加到Cuboid.h中。因此,如果在一个源文件中包含两个标题,那么在没有包含卫士或pragma的情况下,会在那里得到重复的内容


当您包含一个文件时,它本质上与复制文件内容而不是
#include
行相同。对于头文件中的
#include
行也是如此,就像其他任何东西一样。因此,如果头文件包含
,那么再次将其包含在文件中是多余的。所有标准头文件的设计都是为了使包含它们的额外时间没有效果,这就是IDE显示为未使用的原因。我认为另一个问题和答案解决了这一问题(至少对于C)还有页眉保护,这是另一个问题。