天天看點

【轉】王老師 C++ 函數重載和模闆

(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

繼續閱讀