C和C++中泛型編程 - 適應不同類型參數的函數

      首先一個簡單的問題,如何實現交換兩個整數的值? 想必每個有編程經驗的人都能作答。

C語言用指針實現如下:

void swap(int * a, int * b){
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

C++可以使用引用實現如下:

void swap(int & a, int & b){
    int tmp = a;
    a = b;
    b = tmp;
}

順便記錄另外兩個很有意思的實現,不用中間變量tmp (面試中可能會問到):

void swap(int & a, int & b){
    a = a + b;
    b = a - b;
    a = a - b;
}

void swap(int & a, int & b){
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
}

      然後,言歸正傳,假如需要實現任意相同類型兩數交換值應該怎麼辦呢? 比如需要交換兩整數、兩浮點數或者兩個字符。這時,爲每種情況編寫函數實現顯得冗餘, 可以採用泛型編程的方法。C語言中泛型編程需要用到 void*(指向任意類型的指針), C++中則採用函數模板。

新問題的C語言實現如下:

void swap(void * a, void * b, int size){
    char * tmp = malloc(size * sizeof(char));
    memcpy(tmp, a, size * sizeof(char));
    memcpy(a, b, size * sizeof(char));
    memcpy(b, tmp, size * sizeof(char));
    free(tmp);
}

注意:無法對void*直接解引用,所以函數參數需要額外一個size參數標示出 void *指向的數據類型的大小。 相關詳細內容可以參考 http://blog.csdn.net/skyline0623/article/details/6164011


新問題的C++函數模板實現如下:

template<class T>
void swap(T & a, T & b){
    a = a + b;
    b = a - b;
    a = a - a;
}

注意:如果使用C++中的函數模板,很有可能碰到一處很特別的問題,就是如果在函數頭文件中只聲明,而在swap.cpp中實現的話,需要在聲明後再包含.cpp文件, 如

//swap.h
template<class T>
void swap(T & a, T & b);
#include "swap.cpp"

//swap.cpp
template<class T>
void swap(T & a, T & b){
    a = a + b;
    b = a - b;
    a = a - b;
}

否則編譯會報錯。還有一種是在.cpp中加入關鍵字export, 參加http://blog.csdn.net/laixingjun/article/details/8992680

最好的方法是,將函數模板的定義直接放在頭文件中,不要在.cpp文件中。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章