使用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解决问题。
In the C and C++ programming languages, an #include guard, sometimes called a macro guard, header guard, or file guard, is a particular construct used to avoid the problem of double inclusion when dealing with the include directive.
解决方案:
包含保护可确保编译器仅处理该文件一次,无论其被包含多少次。包含保护只是一系列预处理器指令,可保证文件仅被包含一次。
使用的预处理器:
- #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 ,换句话说,它不会处理文件。