(1)連接配接訓示符:通知編譯器,某個函數是由其它語言編寫的。
文法:
1. extern "語言名" 函數原型;
2. extern "語言名"
{
函數原型1;
...
函數原型n;
}
3.extern "語言名"
include 檔案名
原因:C++語言編譯器會對函數重載進行重命名(Name-Mangling);但是在C語言中,由于不允許出現同名的全局函數(靜态全局函數除外),不需進行重命名。是以在程式中如果出現了extern "C" fun(int);就不應出現extern "C" fun(double);
例如:
extern "C" fun(int);
extern "C" fun(double);
int main(void)
fun(3);
fun(3.5);
return 0;
error C2733: second C linkage of overloaded function 'fun' not allowed
(2)函數重載的解析
根據函數調用中的實參,确定要執行的函數。
結果:
1.沒有函數可調用(出錯);
2.恰有一個可調用;
3.有多個可調用,二義性(在編譯時發現)。
解析的時機:
1.函數調用時解析;
void fun(long);
void fun(int);
求:fun(3);
2.取函數位址。
void g(void (*fp)(long));
void g(void (*fp)(int));
求:g(f);
(3)實參類型轉換
1.精确比對。包含4種情形(其中a,b.c稱為左值轉換):
a.從左值到右值的轉換
b.從數組到指針的轉換
c.從函數到指針的轉換
例如: int fun(int);
void g(int (*fp)(int));
求:g(fun);
d.限定修飾符轉換
例如:int *q;
void fun(const int * p);
求:fun(q);
2.提升
a.帶符号或不帶符号的char,short類型轉換為int型。
b.float => double
c.bool => int
3.标準轉換
a.算術類型間的轉換,這與提升a,b是一樣的。
b.整型0到各種指針;各種指針 => void *
c.各種算術指針 => bool
4.使用者自定義轉換
标準轉換序列:
0個或1個左值轉換 -> 0個或1個提升或标準轉換 -> 0個或1個限定修飾符轉換
重載函數解析的過程:
1.确定候選函數集
a.調用點可見的同名函數
b.實參類型定義所屬名字空間中的同名函數
2.确定可行函數集
a.實參個數 <= 形參個數,形參多出的必有預設值。
b.有實參到形參的轉換序列。
3.确定最佳可行函數。
(4)函數模闆
1.功能不同或者是功能太大時不要使用函數重載。
所謂函數重載,是指自動生成各種類型函數的算法。
定義文法:template <模闆參數表>
值類型 函數名 (形參表)
函數體
模闆參數,由兩類參數構成:
a.模闆類型參數
聲明方式: typename 辨別符
表示一個特定類型。
b.模闆非類型參數
聲明方式: 通常的變量聲明
表示一個值。
說明:
值類型,可以是内置類型,使用者定義類型,模闆類型參數
形參表,允許類型如上
函數表,定義的局部變量類型如上。
#include <iostream>
using namespace std;
template <typename T, int size>
T min(T (&a)[size])
int i;
T x = a[0];
for(i = 0; i < size; i++)
{
if (x > a[i])
x = a[i];
}
return x;
template <typename T>
T min(T *a, int size)
int main()
int a[] = {1, 2, 3, -1, 5, 2, 4};
cout << min(a) << endl;
cout << min(a, 7) << endl;
模闆執行個體化:
根據函數調用,自動生成函數。
顯示指定模闆參數文法:
函數名<實參名, ..., 實參名>(實參表);
template <typename T1, typename T2, typename T3>
T1 fun(T2 x, T3 y)
fun<int, int, double>(3, 2.5);
函數實參推演:從函數調用的實參确定模闆參數的過程。
模闆特化文法:
template <>
值類型 函數名<實際模闆參數值>(形參表)
函數體
舉例略。
函數模闆的重載:
1.求候選函數集,較為複雜,略。
2.求可行函數集
3.最佳可行函數集
在寫函數模闆時,可以先寫好特殊類型下的,再寫一般的。例如:排序函數模闆程式如下。
void sort(T *array, int n)
cout << "sort in template 1..." << endl;
//下标
int i, j;
//暫存待排序元素
T tmp;
for(i = 1; i < n; i++)
tmp = array[i];
j = i - 1;
//尋找插入位置
while(j >= 0 && array[j] > tmp)
{
array[j + 1] = array[j];
j--;
}
array[j + 1] = tmp;
template <typename T1, typename T2>
void sort(T1 *array, int n, T2 fun)
cout << "sort in template 2..." << endl;
T1 tmp;
while(j >= 0 && fun(array[j], tmp))
int cmp(int a, int b)
return a > b;
int a[] = {1, 3, 5, 8, 9, 4, 6, 7, 2};
int size = sizeof(a) / sizeof(int);
sort(a, size);
for(int i = 0; i < size; i ++)
cout << a[i] << endl;
cout << endl;
sort(a, size, cmp);
double b[] = {1.0, 3.0, 5.0, 8.0, 9.0, 4.0, 6.0, 7.0, 2.0};
int dsize = sizeof(b) / sizeof(double);
sort(b, dsize);
for(int j = 0; j < dsize; j++)
cout << b[j] << endl;
sort(b, dsize, cmp);
【來 源】:http://blog.csdn.net/nomad2/archive/2006/06/10/787013.aspx