http://hatsukiakio.blogspot.tw/2009/04/c-static.html
基本上物件(.o)之間是獨立的,也就是說compiler只會將一個一個的CPP,編譯成獨立的.o檔,在最後使用linker將物件連結起來,
連結的意思是,假設我在a.cpp時做一個void sum(){};當我在a.h前置宣告void sum(),b.cpp要是include到a.h,並且執行sum();,
他在link的時候會去所有的物件裡面找void
sum()實作的地方,也就是a.cpp,並把他做一個關聯,在執行程式時,就會執行a.cpp的void sum(){}
如前面所說,.o之間是互相獨立的,也就是說可以實作兩個void sum(){}在不同.cpp,如:
///////////////////////////////////
a.cpp
#include “c.h”void sum()
{
Int a = 0;
}
b.cpp
#include “c.h”void sum()
{
Int a = 1;
}
c.cpp
#include “c.h”
void main(){
Sum();
}
c.h
#ifndef cH#define cH
void sum();
#endif
///////////////////////////////////
這在compiler是會過的,並且可以連結起來成exe檔,
問題來了,兩個相同的函式,您怎麼知道他會執行哪一個函式呢
這就牽涉到linker的程式了,基本上我們不可能知道他linker實際上是如何做的,
就我了解並且測試過,
基本上它會跑你專案裡面第一個有void sum(){}的程式碼,也就是a.cpp,
要是您將a.cpp從專案移除,然後再加入a.cpp進入專案,也就是b.cpp會在第一個,您會發現再次link執行它會執行b.cpp的程式裡的void sum(){},
這您可以自己寫個小專案測試看看,就是三個.cpp一個.h,並在軟體程式裡面執行sum();,下中斷點觀察您的程式是如何執行的
這很有趣,所以在寫程式時,要是有所謂的lib函式庫,裡面的cpp你又將他重複加到專案裡,造成有相同的函式,
這時候要是兩個函式是不同程式內容,您要注意.lib和.cpp加入專案裡的順序,不然有時候您會查了半天,發現結果都不是您要的,一直出錯,
最好是將他們用不同的namespace區隔,並命名成不同名子,做一些修改,然後您在使用函式時,假設有兩個namespace,一個是namespace hahaha,一個是namespace hehehe,
假設您要執行namespace hahaha的程式,您就執行hahaha::sum();,這樣就不會錯亂了,
當然您要注意您lib裡用的.h,和您複製一份加到專案裡的.h,他下面這地方也要改,例如原來的是
#ifndef heheheH
#define heheheHNamespace hehehe
{
}
#endif
加入專案相同的.h是
#ifndef hahahaH
#define hahahaHNamespace hahaha
{
}
#endif
總之要做一點區隔,不然會容易有問題,
省了一點點時間,卻花您很多時間在找這個問題
沒有留言:
張貼留言