学习 C++ 头文件定义防卫式声明的原因 , 转载一下
原文:C++防卫式声明
大家知道,我们写.h文件时,通常会加上防卫式声明,有以下两种方式:
1. 宏定义
#ifndef _FILENAME_
#define _FILENAME_
//...
#endif
2. 编译器指令
#pragma once
但是,为什么头文件中需要添加这种防卫式声明呢?如果没有这样的声明,会出现怎样的问题。这里,先看一个例子。
– “Car.h”,代码如下(并没有添加防卫式声明):
// Car.h
class Car
{
// ...
};
– “Person.h”,代码如下(包含了Car.h文件):
// Person.h
#include "Car.h"
class Person
{
public:
Car car;
};
– 在"main.cpp"中,我们同时include两个头文件:
// main.cpp
#include "Car.h"
#include "Person.h"
int main(int argc, const char * argv[]) <br>{
Person p;
}
此时,我们会发现编译出错:Redefinition of ‘Car’.
可是为什么会出现这样的情况呢?
我们需要知道,在预编译阶段,编译器会把.h文件展开,即main.cpp中的代码可以看做是:
class Car
{
// ...
};
class Car
{
// ...
};
class Person
{
public:
Car car;
};
int main(int argc, const char * argv[]) {
Person p;
}
所以,我们可以知道防卫式声明的作用是:防止由于同一个头文件被包含多次,而导致了重复定义。
在这两种声明方式中:
-
#ifndef
依赖于宏定义名,当宏已经定义时,#endif之前的代码就会被忽略,但是这里需要注意宏命名重名的问题; -
#pragma once
只能保证同一个文件不会被编译多次,但是当两个不同的文件内容相同时,仍然会出错。而且这是微软提供的编译器命令,当代码需要跨平台时,需要使用宏定义方式。