2015年12月13日 星期日

C++物件導向的基本知識(物件間的關係.o)


http://hatsukiakio.blogspot.tw/2009/04/c-static.html

基本上物件(.o)之間是獨立的,也就是說compiler只會將一個一個的CPP,編譯成獨立的.o檔,在最後使用linker將物件連結起來

連結的意思是,假設我在a.cpp時做一個void sum(){};當我在a.h前置宣告void sum()b.cpp要是includea.h,並且執行sum();

他在link的時候會去所有的物件裡面找void sum()實作的地方,也就是a.cpp,並把他做一個關聯,在執行程式時,就會執行a.cppvoid 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 heheheH
Namespace hehehe
{

}
#endif

加入專案相同的.h

#ifndef hahahaH
#define hahahaH
Namespace hahaha
{

}
#endif

總之要做一點區隔,不然會容易有問題,
省了一點點時間,卻花您很多時間在找這個問題

沒有留言:

張貼留言