[C++]关于头文件中的防卫式声明
大家知道,我们写.h文件时,通常会加上防卫式声明,有以下两种方式:
1. 宏定义
|
1
2
3
4
|
#ifndef _FILENAME_#define _FILENAME_//...#endif |
2. 编译器指令
|
1
|
#pragma once |
但是,为什么头文件中需要添加这种防卫式声明呢?如果没有这样的声明,会出现怎样的问题。这里,先看一个例子。
-- "Car.h",代码如下(并没有添加防卫式声明):
|
1
2
3
4
5
|
// Car.hclass Car{// ...}; |
-- "Person.h",代码如下(包含了Car.h文件):
|
1
2
3
4
5
6
7
|
// Person.h#include "Car.h"class Person{public: Car car;}; |
-- 在"main.cpp"中,我们同时include两个头文件:
|
1
2
3
4
5
6
|
// main.cpp#include "Car.h"#include "Person.h"int main(int argc, const char * argv[]) <br>{ Person p;} |
此时,我们会发现编译出错:Redefinition of 'Car'.
可是为什么会出现这样的情况呢?
我们需要知道,在预编译阶段,编译器会把.h文件展开,即main.cpp中的代码可以看做是:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
class Car{ // ...};class Car{ // ...};class Person{public: Car car;};int main(int argc, const char * argv[]) { Person p;} |
所以,我们可以知道防卫式声明的作用是:防止由于同一个头文件被包含多次,而导致了重复定义。
在这两种声明方式中:
#ifndef 依赖于宏定义名,当宏已经定义时,#endif之前的代码就会被忽略,但是这里需要注意宏命名重名的问题;
#pragma once 只能保证同一个文件不会被编译多次,但是当两个不同的文件内容相同时,仍然会出错。而且这是微软提供的编译器命令,当代码需要跨平台时,需要使用宏定义方式。
https://www.cnblogs.com/xyq10612/p/5910933.html
[C++]关于头文件中的防卫式声明的更多相关文章
- C++ 多文件编译简述:头文件、链接性、声明与定义
目录 Commen Sense 头文件 链接性 static 与链接性控制 extern 与外部链接性 Reference Commen Sense C++ 在编译时对每个翻译单元(Translati ...
- C++-模板的声明和实现为何要放在头文件中
源: http://blog.csdn.net/lqk1985/archive/2008/10/24/3136364.aspx 如何组织编写模板程序 发表日期: 1/21/2003 12:28:58 ...
- C ++模板的声明和实现为何要放在头文件中?
源: http://blog.csdn.net/lqk1985/archive/2008/10/24/3136364.aspx 如何组织编写模板程序 发表日期: 1/21/2003 12:28:58 ...
- vs2022+resharper创建模板——实现在新建文件的时候自动生成防卫式声明和自定义语句
在网上找了很久如何让visual studio新建文件的时候自动生成注释和防卫式声明,虽然防卫式声明可以用#proga once替代,但是在clion里可以自动生成vs里面没法自动生成还是觉得难受,于 ...
- cctype头文件中的一些内容
1. string 标准库 1.1初始化 string s1; 默认构造函数s1为空 string s2(s1); 将s2初始化为s1的一个副本 string s3(“value”); 将s3初始化为 ...
- Effective Objective-C 2.0 — 第二条:类的头文件中尽量少引入其他头文件
第二条:类的头文件中尽量少引入其他头文件 使用向前声明(forward declaring) @class EOCEmployer 1, 将引入头文件的实际尽量延后,只在确有需要时才引入,这样就可以减 ...
- c语言头文件中定义全局变量的问题
c语言头文件中定义全局变量的问题 (转http://www.cnblogs.com/Sorean/) 先说一下,全局变量只能定义在 函数里面,任意函数,其他函数在使用的时候用extern声明.千万不要 ...
- 将inline、template声明和定义在头文件中
如果要在要在源文件(a.cpp)中内联的展开一个函数(fun),则该源文件(a.cpp)中必须包含此函数(fun)的定义.如果要在多个文件中内联的展开fun,则在所有的源文件中都必须包含fun的定义. ...
- 头文件中的#ifndef/#define/#endif 的作用
在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时,就会出现大量重定义的错误.在头文件中实用#ifndef #define #endif能避免头文件的重定 ...
随机推荐
- Safair浏览器 时间戳转化兼容性问题。
chrome 等浏览器支持 yyyy-MM-dd hh:mm:ss 格式,使用 Date.parse()进行转化 safair 浏览器不知道这种格式,需要将格式设置为 yyyy/MM/dd hh:mm ...
- html标签默认属性值之margin;padding值
一.h1~h6标签:有默认margin(top,bottom且相同)值,没有默认padding值. 在chrome中:16,15,14,16,17,19; 在firefox中:16,15,14,16, ...
- Codeforces Round #364 (Div. 1)(vp) 没什么题解就留坑待填
我就做了前两题,第一题第一次vp就把我搞自闭跑路了,第二题第二次又把我搞自闭了 A. As Fast As Possible 细节题 #include<cstdio> #include&l ...
- PHP编写网页BS结构计算器
利用PHP和Html + javascript 编写一个简单的网页计算器程序,可以根据这种有趣的开发构架出更加有趣的网页.1. [代码]PHP计算器 <html><head& ...
- 配置JDK和Tomcat环境变量(转)
1.安装JDK 安装好JDK后,再配置JDK的环境变量:在“我的电脑”上点右键—>“属性”—>“高级”—> “环境变量(N)”. 新建系统变量JAVA_HOME:C:/Program ...
- Unable to create Debug Bridge:Unable to start adb server:error:cannot parse version
打开Android Studio时报如下错误提示: Unable to create Debug Bridge:Unable to start adb server:error:cannot pars ...
- 「LOJ#10034」「一本通 2.1 例 2」图书管理 (map
题目描述 图书管理是一件十分繁杂的工作,在一个图书馆中每天都会有许多新书加入.为了更方便的管理图书(以便于帮助想要借书的客人快速查找他们是否有他们所需要的书),我们需要设计一个图书查找系统. 该系统需 ...
- zookeeper分布式安装
1.先把zookeeper-3.5.2-alpha.tar上传解压到/usr/local/下重命名为zookeeper ############# zookeeper env ############ ...
- C# HTML解析工具HtmlAgilityPack使用实例(一)
一.生成HTML字符串 //生成DOM字符串结构 HtmlNode container = HtmlNode.CreateNode("<div />"); HtmlNo ...
- CS231n 2016 通关 第四章-NN 作业
cell 1 显示设置初始化 # A bit of setup import numpy as np import matplotlib.pyplot as plt from cs231n.class ...