#pragma once

 

【1】#pragma once这个宏有什么作用?

为了避免同一个文件被include多次,C/C++中有两种宏实现方式:一种是#ifndef方式,一种是#pragma once方式。 在能够支持这两种方式的编译器上,二者并没有太大的区别,但两者仍然有一些细微的区别。

【2】两者的使用方式有何区别?

示例代码如下:

1 //方式一:
2 #ifndef __SOMEFILE_H__
3 #define __SOMEFILE_H__
4 ... ... // 声明、定义语句
5 #endif
6
7 //方式二:
8 #pragma once
9 ... ... // 声明、定义语句

【3】两者各有何特点?

(1)#ifndef

#ifndef的方式受C/C++语言标准支持。它不仅可以保证同一个文件不会被包含多次,也能保证内容完全相同的两个文件(或者代码片段)不会被不小心同时包含。
    当然,缺点就是如果不同头文件中的宏名不小心“撞车”,可能就会导致你看到头文件明明存在,但编译器却硬说找不到声明的状况——这种情况有时非常让人郁闷。
    由于编译器每次都需要打开头文件才能判定是否有重复定义,因此在编译大型项目时,ifndef会使得编译时间相对较
  长,因此一些编译器逐渐开始支持#pragma once的方式。

(2)#pragma once

#pragma once 一般由编译器提供保证:同一个文件不会被包含多次。注意这里所说的“同一个文件”是指物理上的一个文件,而不是指内容相同的两个文件。

你无法对一个头文件中的一段代码作pragma once声明,而只能针对文件。
    其好处是,你不必再担心宏名冲突了,当然也就不会出现宏名冲突引发的奇怪问题。大型项目的编译速度也因此提高了一些。
    对应的缺点就是如果某个头文件有多份拷贝,本方法不能保证他们不被重复包含。当然,相比宏名冲突引发的“找不
  到声明”的问题,这种重复包含很容易被发现并修正。

【4】两者之间有什么联系?

#pragma once 方式产生于#ifndef之后,因此很多人可能甚至没有听说过。目前看来#ifndef更受到推崇。因为#ifndef受C/C++语言标准的支持,不受编译器的任何限制;
 而#pragma once方式却不受一些较老版本的编译器支持,一些支持了的编译器又打算去掉它,所以它的兼容性可能不够好。
 一般而言,当程序员听到这样的话,都会选择#ifndef方式,为了努力使得自己的代码“存活”时间更久,通常宁愿降低一些编译性能,这是程序员的个性,当然这是题外话啦。
    还看到一种用法是把两者放在一起的:
     #pragma once      #ifndef  __SOMEFILE_H__      #define __SOMEFILE_H__      ... ... // 声明、定义语句      #endif
    看起来似乎是想兼有两者的优点。不过只要使用了#ifndef就会有宏名冲突的危险,也无法避免不支持#pragma once的编译器报错,所以混用两种方法似乎不能带来

更多的好处,倒是会让一些不熟悉的人感到困惑。
    选择哪种方式,应该在了解两种方式的情况下,视具体情况而定。只要有一个合理的约定来避开缺点,我认为哪种方
  式都是可以接受的。而这个已经不是标准或者编译器的责任了,应当由程序员自己或者小范围内的开发规范来搞定。

pragram once的更多相关文章

  1. 预处理指令#pragram

    #pragma介绍 #pragma是一个预处理指令,pragma的中文意思是『编译指示』.它不是Objective-C中独有的东西(貌似在C/C++中使用比较多),最开始的设计初衷是为了保证代码在不同 ...

  2. 【开源】.Net Aop(静态织入)框架 BSF.Aop

    BSF.Aop .Net 免费开源,静态Aop织入(直接修改IL中间语言)框架,类似PostSharp(收费): 实现前后Aop切面和INotifyPropertyChanged注入方式. 开源地址: ...

  3. [转]keil使用详解

    第一节 系统概述 Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上.结构性.可读性.可维护性上有明显的优势,因而易学易用.用过 ...

  4. 浅析java内存模型--JMM(Java Memory Model)

    在并发编程中,多个线程之间采取什么机制进行通信(信息交换),什么机制进行数据的同步? 在Java语言中,采用的是共享内存模型来实现多线程之间的信息交换和数据同步的. 线程之间通过共享程序公共的状态,通 ...

  5. iOS - + initialize 与 +load

    一.+ initialize 方法和+load 调用时机 首先说一下 + initialize 方法:苹果官方对这个方法有这样的一段描述:这个方法会在 第一次初始化这个类之前 被调用,我们用它来初始化 ...

  6. Sql Server海量数据插入

    目录 1.前言 2.BULK INSERT 3.简单示例 前言 由于昨天接到一个客户反馈导出数据卡死的问题,于是决定今天模拟一下千万级的数据,然后傻傻的等待插入数据了半天...... 对于海量数据,上 ...

  7. Ninject之旅之二:开始使用Ninject(附程序下载)

    摘要 这篇文章介绍怎样将Ninject添加到实际的项目中,使用Ninject框架最基本的功能.首先用一个Hello World例子介绍怎么添加和使用Ninject.然后用一个更复杂的例子,介绍Ninj ...

  8. 意译:《JVM Internals》

    译者语 为加深对JVM的了解和日后查阅时更方便,于是对原文进行翻译.内容是建立在我对JVM的认识的基础上翻译的,加上本人的英语水平有限,若有纰漏请大家指正,谢谢. 原文地址:http://blog.j ...

  9. iOS 学习资源

    这份学习资料是为 iOS 初学者所准备的, 旨在帮助 iOS 初学者们快速找到适合自己的学习资料, 节省他们搜索资料的时间, 使他们更好的规划好自己的 iOS 学习路线, 更快的入门, 更准确的定位的 ...

随机推荐

  1. C语言学习--链表

    #include "node.h" #include<stdio.h> #include<stdlib.h> //typedef struct _node ...

  2. U盘安装CentOS7

    1:U盘启动,进入安装界面,点击Tab键,修改最后一行如下: ...=initrd.img linux dd quiet 查看centos系统盘符,例如:sdb4 2:重启电脑,进入安装界面,点击Ta ...

  3. python里的Join函数

    用法是将数组里的每个元素用字符连接起来 import string string.join(["aaaa", "bbb"]) 或者: from string i ...

  4. appendGrid的使用

    新的项目中需要使用类似appendGrid的控件,当然开始时是不知道这个控件的,开始是想做成如下这样 这其实是Bugfree的搜索栏,并且我也说不好我要做的这个东西应该叫什么,大体可以说是动态的添加或 ...

  5. 【转】HashMap和HashSet的区别

    原文网址:http://www.importnew.com/6931.html HashMap和HashSet的区别是Java面试中最常被问到的问题.如果没有涉及到Collection框架以及多线程的 ...

  6. DEV控件的使用(二次封装BaseUI)

    一:DEV的安装 直接点击exe文件安装,安装完成之后,将控件添加到工具栏,如下图添加即可 二:注意事项 项目使用的是二次封装的BaseUI,有些属性和事件在BaseUI的控件中由于太多不能全部显示, ...

  7. Number of 1 Bits——LeetCode

    Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also know ...

  8. javascript 关闭窗口,弹出新窗口并带有确认关闭对话框解决办法

    在很多人眼里,北京是一个物欲横流的社会,生活节奏之快,让你一丝都不能停下来,走在路上伴随着人群急速往前涌,或许有些人都不知道要去哪.也不知道自己想要的是什么?在一个浮躁的社会里,多了一些浮躁的人,到处 ...

  9. 金洪林:红邦创衣止于至善_品牌-生活时尚_品牌_YOKA时尚网

    金洪林:红邦创衣止于至善_品牌-生活时尚_品牌_YOKA时尚网 金洪林:红邦创衣止于至善

  10. Iterator荟萃

    package com.starain.Iterator;/*代码整理快捷键为Ctrl+Shift+F * main方法输入快捷键main字符+Alt+/ * 输出快捷键sysout字符+Alt+/* ...