王老师 C++ 函数重载和模板 第二讲

原创 2006年06月10日 20:22:00

(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 i;
 T x = a[0];
 for(i = 0; i < size; i++)
 {
  if (x > a[i])
   x = a[i];
 }
 return x;
}

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.最佳可行函数集

 在写函数模板时,可以先写好特殊类型下的,再写一般的。例如:排序函数模板程序如下。

#include <iostream>
using namespace std;

template <typename T>
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;

 //下标
 int i, j;

 //暂存待排序元素
 T1 tmp;

 for(i = 1; i < n; i++)
 {
  tmp = array[i];
  j = i - 1;
  //寻找插入位置
  while(j >= 0 && fun(array[j], tmp))
  {
   array[j + 1] = array[j];
   j--;
  }
  array[j + 1] = tmp;
 }
}

int cmp(int a, int b)
{
 return a > b;
}

int main()
{
 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);
 for(int i = 0; i < size; i ++)
 {
  cout << a[i] << endl;
 }
 cout << endl;

 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;
 }
 cout << endl;

 sort(b, dsize, cmp);
 for(int j = 0; j < dsize; j++)
 {
  cout << b[j] << endl;
 }

}

 <补充>
1.确定候选函数集

a.调用点可见的同名函数

b.实参类型定义所属名字空间中的同名函数

对于b项,老师举例:

namespace N
{
class A{};
void f(A x){};
void f(int){};
}
void f(double){}

int main()
{
N::A x;
f(x);
}

相关文章推荐

Effective C++ 第二版 22)传引用 23)返回对象 24)函数重载vs缺省值

条款22 尽量用传引用而不用传值 C语言通过传值实现, C++继承传统把它作为默认方式, 除非明确指定, 函数的形参总会通过"实参的拷贝"来初始化, 函数的调用者得到的也是函数返回值的拷贝; "通...

C++中模板类的输入输出流重载函数实现

(转)C++模板类中操作符重载之">"重载   2011-01-10 17:05:31|  分类: IT与程序 |  标签: |字号大中小 订阅 在模板类中输入流“》”...
  • lyyslsw
  • lyyslsw
  • 2012年12月30日 20:47
  • 2540

C++ - 函数模板(function template) 的 重载(overload) 详解 及 代码

函数模板(function template) 的 重载(overload) 详解 及 代码 本文地址: http://blog.csdn.net/caroline_wendy 函数模板(fu...

C++模板类与运算符作为友元函数重载

我自定义了一个模板类并重载了运算符,预定义实现功能为能实现对数组一般操作,类似于vector。 #ifndef ARRAY_H #define ARRAY_H #include using nam...

C++笔记函数重载函数模板

#include using namespace std;class Student { private: int num; int score; public: void s...

C++中函数重载和函数模板的理解

第二遍看C++Primer Plus。。泪目啊。。C++真心难,第一遍是我一年前看的。现在再看感觉好像全新的一样。。。 好了,简单介绍下函数重载,学过编程的都对这个重载很熟悉了。函数重载的判断标识是...

王老师讲解:SQL Server 2005数据库nolock的使用【来自Aisino_BBS】

前两天去安徽航天信息解决A6系统的性能问题,去之前进销存项目组研发人员小苏和小卢把他们认为性能 有问题的SQL已经发给了我,我把优化方法提交给了他们。本以为到那之后会非常轻松,但还是有些插曲在其中。 ...

王老师拼音输入法的算法

N元语言模型的解码算法 分类: 微软拼音输入法开发工程师专栏2011-02-28 16:11 8155人阅读 评论(11) 收藏 举报 ----------------------...
  • fish341
  • fish341
  • 2012年07月02日 17:55
  • 9411

FPGA王老师问答

  • 2013年07月12日 16:41
  • 37KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:王老师 C++ 函数重载和模板 第二讲
举报原因:
原因补充:

(最多只允许输入30个字)