大家知道,我們寫.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[])
{ 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 只能保證同一個文件不會被編譯多次,但是當兩個不同的文件內容相同時,仍然會出錯。而且這是微軟提供的編譯器命令,當代碼需要跨平台時,需要使用宏定義方式。