天天看点

【转】王老师 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

继续阅读