头文件警卫保护

1.5.3文件包含命令和包含警卫
文件包含命令,就是指宏指令#include,这个指令的作用就是包含当前文件所需类型的定义。通常后面有两种形式的包含:第一种是尖括号包含的文件,表示要到系统目录下去寻找;第二种是引号包含的文件,表示在当前工程目录中去寻找。当工程中文件重多时,很有可能出现一个头文件被多次包含的情况。但是,C++中同一个类型被声明两次是非法的,来看一个简单的例子。
CAnimal类定义包含在文件Animal.h中:
#include "stdafx.h"
class CAnimal
{
public:
    CAnimal();
    virtual void Output();
};
CPig类定义包含在头文件pig.h中:
#include "stdafx.h"
#include "Animal.h"
class CPig : public CAnimal
{
public:
    CPig();
    virtual void Output();
};
由于CPig是从类CAnimal上继承下来的,所以在pig.h中需要包含Animal.h的头文件。CHorse类定义包含在头文件horse.h中:
#include "stdafx.h"
#include "Animal.h"
class CHorse : public CAnimal
{
public:
    CHorse();
    virtual void Output();
};
由于CHorse是从类CAnimal上继承下来的,所以在horse.h中需要包含Animal.h的头文件。接下来看一下main函数:
#include "stdafx.h"
#include "pig.h"
#include "horse.h"
int main()
{
    CHorse horse;
    CPig pig;
    return 0;
}
在main函数中使用了CHorse和CPig两个类,所以需要包含这两个类的头文件,但是,这两个类都包含CAnimal的定义,编译器不知道该选择哪个,会报告重复定义的错误。这个时候就需要包含警卫。
所谓包含警卫就是用一组宏命令将头文件包起来,使其不会被重复包含,看Animal.h的例子:
#ifndef ANIMAL_H
#define ANIMAL_H
 
#endif
#ifndef是定义在头文件所有内容之前的,#endif是定义在所有内容之后的,用预编译命令#ifndef和#endif将整个Animal.h头文件中的内容包起来。这样便不会有编译错误了,下面来分析一下。
当main函数所在的文件第一次包含pig.h文件时,同时会导入Animal.h中的内容,这时预编译器分析当前文件没有定义ANIMAL_H,就会在当前文件中定义。当再次包含horse.h文件时,导入Animal.h,发现文件中已经定义了ANIMAL_H,就会查找#else或者#endif,这时会直接跳转到#endif,不会包含当前文件的任何内容。
同理,如果有人想继续从Horse上继承,例如WhiteHorse或lackHorse之类的,在一个地方同时使用,这时就需要在horse.h中加上包含警卫。通常的习惯是在所有的头文件中都加入包含警卫。
注意
关键字#pragma once可以起到相同的作用(仍然有差别)。
posted @ 2019-10-15 11:15  tangjunjun  阅读(286)  评论(0编辑  收藏  举报
https://rpc.cnblogs.com/metaweblog/tangjunjun