关于c++:C11包含守卫ifndef预处理指令pragma-once操作符Pragma

蕴含守卫#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)

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理