有人可以請解釋這是如何工作在C + +?預編譯,編譯和鏈接:
嗨,
首先,在C++編譯分三個步驟完成。該預編譯:
- 尋找「的#include」指令
- 擴大宏
- 處理條件編譯
爲1,當你包含一個文件,該文件中的代碼將「」粘貼到與包含路徑中提供的名稱匹配的第一個文件的編譯文件中。包含路徑作爲輸入參數指定給編譯器(對於使用-I完成的gcc,因此可以使用gcc file.cpp -I。-I/usr/include等)。
This 「代碼粘貼」會產生問題,因爲一個文件可以(通常是)多次包含在項目的不同文件中。這意味着在預處理器完成它的工作後,您可能會遇到同一符號的多個定義。爲了避免由於這個編譯器錯誤,您可以使用「包括衛士」構造,看起來像這樣:
#ifndef SOME_UNIQUE_SYMBOL
#define SOME_UNIQUE_SYMBOL
// all the code in your file goes here
# endif // SOME_UNIQUE_SYMBOL
通過這種方式,第一時間代碼是由預編譯增加(在#包括擴大進程)它將被解析(因爲SOME_UNIQUE_SYMBOL是未定義的)。第二次添加代碼但不會被解析(因爲SOME_UNIQUE_SYMBOL應該是第一次定義)。
Microsoft C++編譯器定義了一個#pragma once
dirrective,您可以將它用作頭文件中的第一行。這可以確保預編譯器只包含一次文件(有效替換組合文件#ifdef
/#define
/#endif
)。
具體在你的例子中,你的#endif
應該是文件的最後一行。
這「的代碼粘貼」也是爲什麼從用C定義你單獨聲明++:您將所有的聲明在頭文件中(傳統命名something.h),並在源文件中定義(傳統命名的東西.cpp),並且只包含頭文件。
您的頭文件應該始終最小。也就是說,他們應該只包含聲明和足夠的#include指令來識別頭文件中的所有內容(函數和類名,常量和定義等)。
你的榜樣應該是:
//Library.h
#ifndef LIBRARY_H_
#define LIBRARY_H_
class Book; // forward declaration, see below
class Library
{
public:
Library();
~ Library();
private:
Book *database;
};
#endif // moved as the last line of the file
在這個例子中,編譯器將需要知道編譯時它是什麼Library類的大小。對於這個需求,它需要知道庫的每個成員變量有多大。
你的情況,你只有一個指向一本書,所以規模將是四個字節(或八個或別的東西,這取決於處理器架構)。
您仍然需要告訴編譯器「Book是一個類」,並且您有兩種方法可以這樣做:使用forward聲明或包含定義Book類的頭文件(替換Book類;代碼與#include "Book.h"
。
向前聲明告訴編譯器「源爲一類治療任何書令牌。以後你會發現這個類的定義」。
如果圖書不會被上找到鏈接(即編譯爲單獨的目標文件並與庫鏈接在一起)編譯器將引發鏈接器錯誤。
如果您使用#include
,您還可以在頭聲明中使用Book實例而不是Book指針(因爲包含它時,確保編譯器在解析Library類時可以計算Book類的大小。
如果使用前置聲明,你仍然必須使用的#include庫類的源文件(在的.cpp類),你實際使用的方法從Book類。
我正在尋找C++如何使用包含在這個實例中的解釋,而不僅僅是對錯誤的修復。 – Stephano 2010-02-19 08:09:52
你的編譯後衛是不適當的:在所有聲明之後,你應該在文件的最後有一個'#endif'。 – 2010-02-19 08:17:55
我推薦這篇文章:http://www.gamedev.net/reference/programming/features/orgfiles/ – fredoverflow 2010-02-19 10:16:14