📜  在C++中包含警卫

📅  最后修改于: 2021-05-30 03:02:58             🧑  作者: Mango

使用C++编程时,我们经常多次使用一个类,因此它需要创建一个头文件并将其包含在主程序中。现在,有时会发生多次直接或间接包含某个头文件的情况,然后重新声明该头文件中声明的类,这会产生错误。要了解包含保护的需求,让我们首先了解一个示例:

程序1:创建一个Animal类并将其保存为“ Animal.h” 。以下是相同的程序:

C++
// C++ program to create a header
// file named as "Animal.h"
#include 
#include 
using namespace std;
  
// Animal Class
class Animal {
    string name, color, type;
  
public:
    // Function to take input
    void input()
    {
        name = "Dog";
        color = "White";
    }
  
    // Function to display the member
    // variables
    void display()
    {
        cout << name << " is of "
             << color << endl;
    }
};


C++
// C++ program to create header file
// named as Dog.h
  
// Include the header file "Animal.h"
#include "Animal.h"
  
// Dog Class
class Dog {
    Animal d;
  
public:
    // Take input to member variable
    // using function call in another
    // header file
    void dog_input() { d.input(); }
  
    // Function to display the member
    // variable using function call
    // in another header file
    void dog_display() { d.display(); }
};


C++
// C++ program to illustrate the
// include guards
#include "Animal.h"
#include "Dog.h"
#include 
using namespace std;
  
// Driver Code
int main()
{
    // Object of Dog class in
    // "Dog.h" header file
    Dog a;
  
    // Member Function Call
    a.dog_input();
    a.dog_display();
  
    return 0;
}


C++
// Checks if _ANIMALS IF DECLARED
#ifndef _ANIMALS_
  
// Defines _ANIMALS_ if above
// conditions fails
#define _ANIMALS_
  
#include 
#include 
using namespace std;
  
// Animal Class
class Animal {
    string name, color, type;
  
public:
    // Function to take input to
    // member variable
    void input()
    {
        name = "Dog";
        color = "White";
    }
  
    // Function to display the
    // member variable
    void display()
    {
        cout << name << " is of"
             << color << endl;
    }
};
#endif // _ANIMALS_


程序2:创建Dog类并将其另存为Dog.h。记住要包括上面声明的“ Animal.h”头文件:

C++

// C++ program to create header file
// named as Dog.h
  
// Include the header file "Animal.h"
#include "Animal.h"
  
// Dog Class
class Dog {
    Animal d;
  
public:
    // Take input to member variable
    // using function call in another
    // header file
    void dog_input() { d.input(); }
  
    // Function to display the member
    // variable using function call
    // in another header file
    void dog_display() { d.display(); }
};

程序3:创建一个main.cpp文件,并在两个头文件的上方都包含该文件。以下是相同的程序:

C++

// C++ program to illustrate the
// include guards
#include "Animal.h"
#include "Dog.h"
#include 
using namespace std;
  
// Driver Code
int main()
{
    // Object of Dog class in
    // "Dog.h" header file
    Dog a;
  
    // Member Function Call
    a.dog_input();
    a.dog_display();
  
    return 0;
}

输出:现在,当执行上述程序“ main.cpp”时,将发生以下错误:

说明:当使用include Animal.h编译“ main.cpp”程序并定义Animal类时,此后在包含Dog.h时Animal.h被包含在内,并且在主程序中有Animal Class的两个定义,这就是为什么出现此错误的原因生成的。现在让我们使用include Guards解决问题。

解决方案:
包含保护可确保编译器仅处理该文件一次,无论其被包含多少次。包含保护只是一系列预处理器指令,可保证文件仅被包含一次。
使用的预处理器:

  • #ifndef:如果未定义,则确定提供的宏是否不存在。
  • #define:定义宏。
  • #endif:关闭#ifndef指令。

仅当未定义宏或带有#ifndef的标识符时,才会执行#ifndef#endif之间的语句块。

句法:

#ifndef ANIMAL(Any word you like but unique to program)
#define ANIMAL(same word as used earlier)

class Animal {
    // Code
};

#endif

因此, “ Animal.h”头文件应声明为:

C++

// Checks if _ANIMALS IF DECLARED
#ifndef _ANIMALS_
  
// Defines _ANIMALS_ if above
// conditions fails
#define _ANIMALS_
  
#include 
#include 
using namespace std;
  
// Animal Class
class Animal {
    string name, color, type;
  
public:
    // Function to take input to
    // member variable
    void input()
    {
        name = "Dog";
        color = "White";
    }
  
    // Function to display the
    // member variable
    void display()
    {
        cout << name << " is of"
             << color << endl;
    }
};
#endif // _ANIMALS_

输出:

说明:运行main.cpp时,将包括Animal.h并声明动物类。在这里, Animal.h标头的第一行在执行时并且未定义为_ANIMALS_时,代码将正常执行。当包含Dog.h头文件而又包含Animal.h时,这次_ANIMALS_是在程序中定义的,因此第一行#ifndef条件为true,整个代码被跳过到最后一行,即#endif 。简单来说,如果预处理器定义了该名称,那么它将跳过整个文件并转到#endif ,换句话说,它不会处理文件。

要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”