包含守卫#ifndef
通常用于放在头文件中,防止文件内容被多次包含在同一个文件中:

//---------------------------test.h begin-----------------------------
#ifndef TEST_H
#define TEST_H
 
void test();
 
#endif
//---------------------------test.h end-------------------------------
//---------------------------main.cpp begin-------------------------------
 
#include "test.h"    //第一次被#include时,由于没有定义TEST_H,test.h的内容会被包含进来
#include "test.h"    //第二次被#include时,由于在第一次#include时已经通过#define定义了TEST_H,所以test.h的内容不会被重复包含
 
//---------------------------main.cpp end---------------------------------

这种方式的优点是:
1.可以对文件内容进行局部控制。
2.如果多个文件具有相同文件内容,但文件名不同,那么包含守卫也可以成功的避免多次包含的问题。

这种方式的缺点是:
1.包含守卫的名字要保证唯一性,否则如果不同文件用了相同的包含守卫,会导致只有一个文件被真正的包含进来。
2.由于是方生在预编译期间,需要打开文件才能对包含守卫进行判断,所以编译的时间会稍长。

预处理指令#pragma once
定义在文件中,可指示编译器,这个文件只能被编译一次:

#pragma once
     
void test();

这种方式的优点是:
1.由于只被编译一次,所以编译速度较快。

这种方式的缺点是:
1.不能对文件的局部内容进行控制,只能对文件整体控制。
2..如果多个文件具有相同文件内容,但文件名不同,那么虽然每个文件都只会被编译一次,但相同的文件内容,会出现重复定义的编译错误:

//---------------------------human1.h begin-----------------------------
#pragma once
 
struct Human{
    std::string name;
    int age;
};
 
struct Human xiaoming = {"xiaoming", 10};
 
//---------------------------human1.h end-------------------------------
//---------------------------human2.h begin-----------------------------
#pragma once
 
struct Human{
    std::string name;
    int age;
};
 
struct Human xiaoming = {"xiaoming", 10};
 
//---------------------------human2.h end-------------------------------
//---------------------------main.cpp-----------------------------
#include <string>
#include "human1.h"
#include "human2.h"
 
using namespace std;
 
int main()
{
    return 0;
}
 
//---------------------------main.cpp end-------------------------------
 
由于human1.h和human2.h都定义了struct Human,所以编译时会报错:redefinition of 'struct Human'
由于human1.h和human2.h都定义了xiaoming,所以编译时会报错:redefinition of 'Human xiaoming'

操作符_Pragma
C++11支持了操作符_Pragma,_Pragma("once")的效果与#pragma once相同,不过由于_Pragma是操作符,所以可以应用于宏定义中:

#define PRAGMA(x) _Pragma(#x)
PRAGMA(once)

天天事事了了
1 声望0 粉丝