1.函数重载的概念
在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。您不能仅通过返回类型的不同来重载函数!
函数重载的关键是函数的参数列表——也称为函数特征标。如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则它们的特征标相同,而变量名是无关紧要的。c++允许定义名称相同的函数,条件是它们的特征标不同。如果参数数目或参数类型不同,则特征标也不同。
2.一个简单的演示例子
1. 演示的源码
#include <iostream>
using namespace std;
void print(const char *str, int width); //#1
void print(double d, int width); //#2
void print(long l, int width); //#3
void print(int i, int width); //#4
void print(const char *str); //#5
int main()
{
//梦悦foundation
unsigned int year = 2021;
print("meng-yue-foundation", 15);
print("meng-yue-foundation");
print(1999.0, 10);
print(29, 12);
print(19L, 15);
//print(year, 6);
return 0;
}
void print(const char *str, int width)
{
cout << "#1 print(const char *str, int width)" << endl;
}
void print(double d, int width)
{
cout << "#2 print(double d, int width)" << endl;
}
void print(long l, int width)
{
cout << "#3 print(long l, int width)" << endl;
}
void print(int i, int width)
{
cout << "#4 print(const char *str, int width)" << endl;
}
void print(const char *str)
{
cout << "#5 print(const char *str)" << endl;
}
运行结果如下
book@book-desktop:~/meng-yue/c++/function/02$ ./FunctionOverload
#1 print(const char *str, int width)
#5 print(int , int width)
#2 print(double d, int width)
#4 print(const char *str, int width)
#3 print(long l, int width)
book@book-desktop:~/meng-yue/c++/function/02$
2. unsigned int year = 6, print(year, 6);与谁匹配?
#include <iostream>
using namespace std;
void print(const char *str, int width); //#1
void print(double d, int width); //#2
void print(long l, int width); //#3
void print(int i, int width); //#4
void print(const char *str); //#5
int main()
{
//梦悦foundation
unsigned int year = 2021;
print("meng-yue-foundation", 15);
print("meng-yue-foundation");
print(1999.0, 10);
print(29, 12);
print(19L, 15);
print(year, 6);
return 0;
}
void print(const char *str, int width)
{
cout << "#1 print(const char *str, int width)" << endl;
}
void print(double d, int width)
{
cout << "#2 print(double d, int width)" << endl;
}
void print(long l, int width)
{
cout << "#3 print(long l, int width)" << endl;
}
void print(int i, int width)
{
cout << "#4 print(const char *str, int width)" << endl;
}
void print(const char *str)
{
cout << "#5 print(int , int width)" << endl;
}
编译报错了,匹配的函数太多了,有歧义!
book@book-desktop:~/meng-yue/c++/function/02$ g++ -o FunctionOverload FunctionOverload.cpp
FunctionOverload.cpp: In function ‘int main()’:
FunctionOverload.cpp:20: error: call of overloaded ‘print(unsigned int&, int)’ is ambiguous
FunctionOverload.cpp:4: note: candidates are: void print(const char*, int) <near match>
FunctionOverload.cpp:5: note: void print(double, int)
FunctionOverload.cpp:6: note: void print(long int, int)
FunctionOverload.cpp:7: note: void print(int, int)
book@book-desktop:~/meng-yue/c++/function/02$
首先它是unsigned int类型,他不与任何原型匹配。没有匹配的原型并不会自动停止使用其中的某个函数。因为c++将尝试使用标准类型转换强制进行匹配。如果#2原型是print()唯一的原型。则函数调用print(year,6)将把year转换为double类型。但在上面的代码中,有4个将数字作为第一个参数的原型。因此有4种转换year的方式。在这种情况下,c++将拒绝这种函数调用,并将其视为错误!
3. 一些看起来彼此不同的特征标是不能共存的
例如,请看下面的两个原型。
double cube(double x);
double cube(double & x);
从形式上来看,好像是符合函数重载的,因为他们的特征标看起来不同,但是编译器看到下面的代码不知道使用哪个原型
cout << cube(x);
为了避免这种混乱,编译器在检查特征标的时候,将把类型引用和类型本身视为同一个特征标。
3. const和非const在函数函数重载当中的注意事项
void function(char *bits);
void function(const char *cbits);
void demo(char *bits);
void demo_const_char(const char *bits);
下面列出了各种函数调用对应的原型
const char p1[20] = "梦悦foundation";
char p2[30] = "梦悦foundation";
function(p1);//------>匹配void function(const char *cbits);
function(p2);//------》匹配void function(char *bits);
demo(p1);//------》什么都不匹配,还会报错
demo(p2);//-------》匹配void demo(char *bits);
demo_const_char(p1);
demo_const_char(p2);//两个都匹配到 void demo_const_char(const char *bits);
function()
函数有两个原型,一个用于const 指针,一个用于常规指针,编译器将根据实参是否为const来决定使用哪个原型。
demo()
函数只会匹配非const 参数, 而demo_const_char()
函数可以与带const 或者不带 const参数 匹配,之所以出现这种差别,主要是由于允许将 非 const值赋给 const 形参是合法的,但是 将const 值赋值给 非const 是不合法的,因为合法的话,不就相当于可以更改const的值了吗?
1. demo_const.cpp 用来演示const与非const在函数重载当中的注意事项
demo_const.cpp 的源码
#include <iostream>
using namespace std;
void function(char *bits);
void function(const char *cbits);
void demo(char *bits);
void demo_const_char(const char *bits);
int main(int argc, char *argv[])
{
const char p1[20] = "梦悦foundation";
char p2[30] = "梦悦foundation";
function(p1);//------>匹配void function(const char *cbits);
function(p2);//------》匹配void function(char *bits);
//demo(p1);//------》什么都不匹配,还会报错
demo(p2);//-------》匹配void demo(char *bits);
demo_const_char(p1);
demo_const_char(p2);//两个都匹配到 void demo_const_char(const char *bits);
return 0;
}
void function(char *bits)
{
cout << " function(char *bits) " << endl;
}
void function(const char *cbits)
{
cout << " function(const char *cbits) " << endl;
}
void demo(char *bits)
{
cout << " demo(char *bits) " << endl;
}
void demo_const_char(const char *bits)
{
cout << " demo_const_char(const char *bits) " << endl;
}
这一行如果不注释掉还会报错//demo(p1);
book@book-desktop:~/meng-yue/c++/function/02$ g++ -o demo_const demo_const.cpp
demo_const.cpp: In function ‘int main(int, char**)’:
demo_const.cpp:17: error: invalid conversion from ‘const char*’ to ‘char*’
demo_const.cpp:17: error: initializing argument 1 of ‘void demo(char*)’
book@book-desktop:~/meng-yue/c++/function/02$
说明了 const char *
确实不能转化成 char *
把报错那一行注释掉,看一下运行结果
book@book-desktop:~/meng-yue/c++/function/02$ ./demo_const
function(const char *cbits)
function(char *bits)
demo(char *bits)
demo_const_char(const char *bits)
demo_const_char(const char *bits)
book@book-desktop:~/meng-yue/c++/function/02$
4. 去哪获取笔记和详细的资料
代码资料的路径