以c++為例,假設有兩個功能a.cpp\b.cpp,以下為a.cpp對於的.**件(只做演示)
class a
;
b.**件如下
#include "a.h"
class b;
首先,建乙個main.cpp,具體如下
#include "a.h"
#include "b.h"
int main()
此處只用作演示上文提及的錯誤生成過程,所以啥也沒寫。
而當我們編譯的時候,神奇的事情出現了,編譯器彈出來這麼乙個錯誤:
由於vs現在已經有中文翻譯了,所以出現那個令人絕望的「redefined *** ...」已經不再出現,但是這個問題本身依然讓人覺得有點摸不著頭腦。實際上,這是由於c\c++編譯器在編譯的預處理階段是將include " .h"中的內容直接插入對應的.cpp檔案中,所以,既包含了"a.h",又包含了「b.h」的main.cpp中就會出現兩個a類,重定義即由此而來。
具體解決方法:
本文採用的是用**件中的巨集來解決這一問題,具體為在a.h中加入
#ifndef _a_h_
#define _a_h_
void f();
class a
;#endif // !_a_h_
使得a類值插入一次,因此解決了重定義的問題。
同樣,若在.**件中定義變數global,如
#ifndef _a_h_
#define _a_h_
int global;
void f();
class a
;#endif // !_a_h_
同時在a.cpp中寫乙個函式
#include "a.h"
void fun()
在進行編譯時出現了這樣乙個錯誤
又感覺很頭大啊,錯誤在**呢?
咱們來詳細看一下編譯發生的過程:
在上面我們不難發現,每個cpp檔案都是單獨編譯的,其只有到最後鏈結的時候才會在一起出現,結合上面的知識我們就知道了,每個包含include " a.h"的cpp都會生成乙個int global變數,但在編譯是各不影響,直到鏈結時才會出現「重定義」這一問題,這就是為什麼我們不能在.**件中定義變數,而要將全域性變數通過extern關鍵字甩出來的原因了。
寫在最後:這篇文章是從翁愷老師的c++課中總結出來的,儘管是一些在初學階段出現的問題,但其中展現出來的c\c++編譯器的相關知識卻非常深刻,聽完之後收益良多
C C 鏈結有關的問題
如果我們需要引用乙個外部庫裡面的變數或函式,要涉及到extern,具體該怎麼寫呢?下面是一小段例子函式 假設我們有2個原始檔hello.h和hello.cpp hello.h的 如下 ifdef cplusplus extern c endifhello.cpp的 如下 extern const c...
C C 中的 問題
符號是c c 之中非常有趣的,前段時間發現乙個很好玩的算式,在tc和vc下面獲得不同的結果。i 0 i i i i 熟悉c語言的能夠分析一下,首先是i 0,i的初值為0,第二步是很多個 號,我們大致可以推導下它的執行過程 先執行第乙個 i,i 1,然後 i,i 2,繼續 i,i 3,最後再進行 計算...
C C 中的堆和棧整理
一 預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放 程式結束時可能由os 注意它與資料結...