注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。
测试环境:Ubuntu 10.10
GCC版本:4.4.5
一、自然语言中的上下文
1)你知道下面词汇中“洗”字的含义吗?
二、重载的概念
1)重载(Overload)
- 同一个标识符在不同的上下文有不同的意义
- 如:
* “洗”和不同的词汇搭配后有不同的含义
洗衣服,洗脸,洗脑,洗马桶,……
* “play”和不同的单词搭配后有不同的含义
play chess,play piano,play basketball,……
三、思考
重载在自然语言中随处可见的。那么程序设计中是否也有重载呢?
四、C++中的函数重载
1)函数重载(Function Overload)
- 用同一个函数名定义不同的函数
- 当函数名和不同的参数搭配时函数的含义不同
int func(int x)
{
return x;
}
int func(int a, int b)
{
return a + b;
}
int func(const char* s)
{
return strlen(s);
}
编程实验
函数重载初探
8-1.cpp
#include <stdio.h>
#include <string.h>
int func(int x)
{
return x;
}
int func(int a, int b)
{
return a + b;
}
int func(const char* s)
{
return strlen(s);
}
int main(int argc, char *argv[])
{
printf("%d\n", func(3)); //3
printf("%d\n", func(4, 5)); //9
printf("%d\n", func("D.T.Software")); //12
return 0;
}
操作:
1) g++ 8-1.cpp -o 8-1.out编译正常,打印结果:
3
9
12
分析:同一个函数名搭配不同参数,调用相匹配的函数来实现不同功能。
2)函数重载至少满足下面的一个条件:
#include <stdio.h>
#include <string.h>
int func(int a, const char *s)
{
printf("1\n");
return a;
}
int func(const char *s, int a)
{
printf("2\n");
return strlen(s);
}
int main(int argc, char *argv[])
{
int a = func(1, "abc"); //调用int func(int a, const char *s)
int length = func("abc", 1);//调用int func(const char *s, int a)
printf("a = %d\n", a);
printf("length = %d\n", length);
return 0;
}
操作:
1) g++ test.cpp -o test.out编译正常,打印结果:
1
2
a = 1
length = 3
分析:参数顺序不同,构成了函数重载。
3)当函数默认参数遇上函数重载会发生什么?
int func(int a, int b, int c = 0)
{
return a * b * c;
}
int func(int a, int b)
{
return a + b;
}
int main()
{
int c = func(1,2); //Which one?
return 0;
}
编程实验
函数默认参数VS函数重载
8-2.cpp
#include <stdio.h>
int func(int a, int b, int c = 0) //只要c有默认值,func调用就会产生二义性
{
return a * b * c;
}
int func(int a, int b)
{
return a + b;
}
int main(int argc, char *argv[])
{
int c = func(1, 2);
return 0;
}
操作:
1) g++ 8-2.cpp -o 8-2.out编译错误:
8-2.cpp:15:19: error: call of overloaded 'func(int, int)' is ambiguous
int c = func(1, 2);
错误:调用重载'func(int, int)'函数是不确定的
分析:
虽然有重载关系,但是不知道调用那个函数!!!(二义性)主要是c=0干扰了编译器执行结果。
4)编译器调用重载函数的准则
- 将所有同名函数作为候选者
- 尝试寻找可行的候选者
*精确匹配实参
*通过默认参数能够匹配实参
*通过默认类型转换匹配实参
- 匹配失败
*最终寻找到的候选函数不唯一,则出现二义性,编译失败
*无法匹配所有候选者,函数未定义,编译失败
5)函数重载的注意事项
- 重载函数在本质上是相互独立的不同函数
- 重载函数的函数类型不同(提示:函数指针)
- 函数返回值不能作为函数重载的依据
函数重载是由函数名和参数列表决定的!
编程实验
函数重载的本质——不同功能的函数
8-3.cpp
#include <stdio.h>
int add(int a, int b) // 函数类型:int(int, int)
{
return a + b;
}
int add(int a, int b, int c) // 函数类型:int(int, int, int)
{
return a + b + c;
}
int main()
{
printf("%p\n", (int(*)(int, int))add);
printf("%p\n", (int(*)(int, int, int))add);
return 0;
}
操作:
1) g++ 8-3.cpp -o 8-3.out编译正确,打印结果:
0x804841d
0x804842a
分析:
调用函数名相同的add,却打印了不同函数地址,说明构成了函数重载。
小结:
1)函数重载是C++中引入的概念
2)函数重载用于模拟自然语言中的词汇搭配
3)函数重载使得C++具有更丰富的意义表达能力
4)函数重载的本质为相互独立的不同函数
5)C++中通过函数名和函数参数确定函数调用