在編譯程序的時候,遇到了1個問題,花點時間記錄1下:
在Qt中創建1個類后,1般是先在.h文件中聲明變量與函數,然后在對應的.cpp文件中對各個函數進行定義,這在平常使用中沒有任何問題,今天在使用Qt時,在各.cpp源文件編譯時出現了許多multiple definition of XXX的毛病:
搜索了網上1些資料,總算是解決multiple definition of 的方法:
問題解決方法之1:
根據網上的解釋,multiple definition of 緣由是由于在屢次包括global.h時重復定義了變量和函數。問題是檢查進程序后,發現其實不存在重復定義的變量和函數,在1條論壇評論中嘗試了1種簡單粗魯的方法……以Qt項目為例,在項目的Debug文件夾中找到編譯時生成的o文件,如:
c和c++編譯.c,cpp文件,每一個文件都生成.o文件,再把所有的.o文件鏈接成最后的履行程序,若o文件有問題,是沒法生成履行文件的。將已存在的o文件刪除之,重新編譯并生成新的o文件,結果在沒有其他問題的情況下成功生成履行程序。(我就是屬于這類情況…在確認代碼中已無明顯毛病時可以1試)
問題解決方法之2:
當多個文件包括同1個頭文件時,并且你的.h文件里面沒有加上條件編譯。
而當多個文件包括同1個頭文件時,而頭文件中沒有加上條件編譯,就會獨立的解釋,然后生成每一個文件生成獨立的標示符。在編譯器連接時,就會將工程中所有的符號整合在1起,由于,文件中有重名變量,因而就出現了重復定義的毛病。
給每個頭文件加上條件編譯,避免該文件被屢次援用時被屢次解釋,這是個應當是習慣。這個方法會解決大部份低級問題。在創建Qt類時已默許生成條件編譯:
#ifndef TEST_H
#define TEST_H
......
#endif
就會獨立的解釋,然后生成每一個文件生成獨立的標示符。在編譯器連接時,就會將工程中所有的符號整合在1起,由于,文件中有重名變量,因而就出現了重復定義的毛病。
因此可以給每個頭文件加上條件編譯,避免該文件被屢次援用時被屢次解釋,這是個應當是習慣。這個方法會解決大部份低級問題。
問題解決方法之3:
當以上方法無效時,可以把所有的全局變量放入1個頭文件 global.h (名字隨便起,但要加條件編譯)中,每個變量前面加extern,聲明1下這些變量將在其它文件中定義。 然后建立1個和頭文件名字對應的.c or .cpp文件 如global.c。在里面聲明所有的全局變量。例如:void(*Handl_Display)();
然后,讓觸及到全局變量的文件include ”global.h“。這樣編譯時,會先對global.c編譯生成1個global.o ,然后再和其它文件的.o鏈接生成可履行文件。
在1篇文章: http://blog.csdn.net/wu070815/article/details/8781762 中提到的另外一種解決方法:
在變量前加static,聲明成靜止變量。
這個方法雖然可以解決multiple definition的問題,但是卻會引發其他問題。
問題以下:
3個文件,a.h,a.c,b.c;
在a.c和b.c 都include了a.h。
在b.c中調用a.c中的函數對a.h中的變量進行賦值,但事實上b.c中的變量仍沒被賦值。
問題分析:
static的含義是迫使那個變量只在某個文件可見。
假定你在頭文件定義static x;
且這個頭文件分別被a.c和b.c包括;
實質是在a.c和b.c里會分別定義1個名字叫x的變量,兩個x毫無關系。
在a.c里修改x,他不會致使b.c里的x變化。