C++的函式和模板函式 (轉)

worldblog發表於2007-08-17
C++的函式和模板函式 (轉)[@more@] 在c++沒有模板(template)機制的時候,我們使用的就是普通的,我們要實現一個加法函式,他能夠對兩個引數求和,並根據引數的型別返回具有適當型別的值,就必須手工書寫所有的程式碼:

short sum(short a,short b) {return a+b;}

int sum(int a,int b){return a+b;}

float sum(float a,float b){ return a+b;}

……

非常麻煩,可以用c++的模板函式來表達“通用型的函式”

template

T sum(T a,T b)

{

  return a+b;

}

儲存為sumtest.h

現在,c++可以根據我們sum函式的引數型別“現場”生成一個適當的函式,然後呼叫它。例如:

#include

#include “sumtest.h”

using namespace std;

 int main(void)

{

  float fa=1,fb=3,fs;

  fs=sum(fa,fb);

  cout<

}

[@localhost html]# g++ -o sumtest sumtest.cpp

[root@localhost html]# ./sumtest

sum(float,float) 1 and 3=4

看上面的程式碼,c++編譯器為我們生成一個“float版本”的sum函式並呼叫它。如果我們給出的引數型別不一樣,則編譯器會報錯。例如

#include

#include "sumtest.h"

using namespace std;

int main(void)

{

  float fa=1,fs;

  int Ib=3;

  fs=sum(fa,Ib);

  cout<

  return 0;

}

[root@localhost html]# g++ -o sumtest sumtest.cpp

sumtest.cpp: In function `int main ()':

sumtest.cpp:10: no matching function for call to `sum (float &, int

&)'

由於函式模板並不支援兩個不同型別的引數求和,所以C++編譯器會報告無法生成真正的函式,從而讓員有機會知道呼叫引數除了問題。

如果不是用模板函式而用普通函式,即使引數型別不完全一致也可能會透過編譯。例如

#include

using namespace std;

 :namespace prefix = o ns = "urn:schemas--com::office" />

float sum(float a,float b)

{

  return a+b;

}

 

int main(void)

{

  float fa=1,fs;

  int Ib=3;

  fs=sum(fa,Ib);

  cout<

  return 0;

}

[root@localhost html]# g++ -o sumtest sumtest.cpp

[root@localhost html]# ./sumtest1

sum(float,Int) 1 and 3=4

因為c++中,int型別可以自動轉換成float型別,於是這種情況下不會報錯。

函式模板不是真正的函式,它只是c++編譯器生成具體函式的一個模子。所以不能把函式模板的宣告和定義分開放在不同的中,而普通的函式可以這樣做。

 

C++函式還有一個問題就是和c的函式的區別。最近在 C/C++論壇上出現了幾個關於c語言寫的程式碼,c編譯器可以透過編譯,採用c++編譯器就不行了。就是這個問題。

發表於: -09-25 20:03  發表主題: 關於C與C++的一些問題?(具有挑戰性!)  請問各位:我在unix環境下遇到如下問題: 用C編譯器編譯時:如我的源程式都位於一個目錄中如, 其中有如下檔案: /web/tool.c /web/webserver.c 說明:tool.c中定義了一些函式,而沒有相應的tool.h標頭檔案。 webserver.c呼叫了tool.c中的函式, 請問是不是不用在webserver.c中包含tool.c檔案就可以呼叫tool.c中的函式嗎? 而在我的下是可以的 當我改用C++編譯器編譯時則總是提示webserver.c中呼叫而在tool.c中定義的函式沒有定義 請問這是怎麼回事, 我應該怎麼解決這個問題? 我現在已經是 幾天沒有進展了,過幾天就要交貨了, 高手救救我!!!!!

發表於: 2003-09-25 19:49  發表主題: 用C++編譯器編譯C程式需要注意什麼問題?  我用C++編譯器編譯C塬程式,為什麼有很多函式明明已經定義而編譯器提示沒有定義,而我的C程式用C編譯器完全正常, 請問各位是什麼原因? 小弟正等著就命呢,請指點密集

他們的問題實質上都是同樣的問題:C和C++對函式的處理是不一樣的。對比於C語言的函式,C++增加了過載(overloaded)、內聯(inline)、const和virtual四種新機制。C++的函式可以過載,c++為了實現過載的這個特性,c++編譯器必須以某種辦法區分那些名字相同但引數不同的函式。c++透過編碼把引數資訊融入了最終輸出的符號中,比如函式 int fun(int ){ ……}

g++把它的名字改裝成了_Z3funi
上面“_Z”是g++對函式的固定標示,所有的函式的最終名字都帶有“_Z";3表示隨後的3個字元是一個標示符,fun就是中的函式名,i標示帶有int型別的引數。
而且c++的面向的特性也要求編譯器以適當的方式改裝函式。
由於c++對函式名字的處理,我們要呼叫c的函式,就必須明確的告訴c++編譯器,通知他不擴充套件函式名, C++提供了C連線指定符號extern“C”來解決名字匹配問題:
extern "C" int fun(int);


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-963767/,如需轉載,請註明出處,否則將追究法律責任。

相關文章