王老师 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);
}

c++函数重载和函数模板

上学期学了C++,可是忘得差不多了 一、函数重载 1、函数重载挺简单的,按我的理解就是相同功能的函数可以用相同的名字,通俗点就是中文里的我能做什么,比如做饭,做菜,虽然做的东西不一样,但是...
  • u011282704
  • u011282704
  • 2014年09月24日 00:16
  • 788

C++ 函数模板(十四)--template 泛型函数模板、通用函数、重载模板

#include #include using namespace std; //函数模板,typename 等价于 class template void test(AnyType &a, A...
  • Jason_chen13
  • Jason_chen13
  • 2016年09月07日 12:01
  • 735

C++ 模板函数和非模板函数的重载

关于函数的重载机制,是一个比较复杂的问题,其中涉及到了优先级定义和最佳匹配等问题,如果要阐述清楚,恐怕不是一两篇文章就能说的明白。但是如果掌握了一些常用的“规律”,对于了解程序对重载函数是如何进行选择...
  • colddie
  • colddie
  • 2013年03月12日 16:29
  • 2403

c++重载与模板

一、 模板是泛型编程的重要支持,函数和类模板在STL中运用的非常广泛,首先谈谈c中的函数重载和c++中的函数模板的区别: 1、首先,函数重载是函数名相同,但参数个数和类别不同,如果增加参数个数和参数型...
  • monkey_D_feilong
  • monkey_D_feilong
  • 2016年07月12日 19:48
  • 1002

C++中模板类的友元重载

一个由《程序员面试宝典》引出的问题。 描述模板类的友元重载,用C++代码实现? 这实际上考察的是下面几个问题: 1.模板类的编写 2.模板类中友元函数的编写 3.什么时候会用到友元重载?答案...
  • u012501459
  • u012501459
  • 2015年03月10日 16:41
  • 1692

【c++模板笔记一】模板的介绍及其重载

本文你将学到: 1.为什么要引入模板。 2.怎么去定义和使用模板 3.分析模板的实现方法和隐式推断规则。 4.模板重载的规则。...
  • zmyoukonw
  • zmyoukonw
  • 2015年02月11日 21:15
  • 1236

C++ STL 基础及应用(2) 模板与操作符重载

模板是 C++ 语言中重要的概念。它提供了一种通用的方法来开发重用的代码,即以创建参数化的 C++ 类型。 本章将阐述一些具体的 STL 模板思想,并简单介绍操作符重载与模板的联系。 文中将给出一个简...
  • Raito__
  • Raito__
  • 2016年05月22日 17:13
  • 2556

浅谈函数重载和模板函数

术语“函数重载”指的是可以有多个同名的hanshu
  • a1037488611
  • a1037488611
  • 2014年04月20日 17:08
  • 1080

C++泛型编程1——函数模板实例化,模板参数,重载及特化

在C++中我们都知道引入了函数重载,那么在实际应用过程中:   如果我们想要实现一个加法函数,我们可以写出很简单的代码:   int ADD(int a,int b) {   return a+b...
  • lixungogogo
  • lixungogogo
  • 2016年08月13日 02:09
  • 2068

C++之模板(模板函数+模板类+STL+重载[未完待续])

模板 模板就是把类型当做参数,假设有一下代码 代码1:int max(int a, int b){ return (a > b) ? a; b; } char max(char a, char b...
  • u013486414
  • u013486414
  • 2017年03月06日 18:48
  • 538
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:王老师 C++ 函数重载和模板 第二讲
举报原因:
原因补充:

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