本次内容比较具体,都是c++一些特有的功能,在一些特定情况下作用非常大。
函数 默认参数
简而言之就是:调用该函数时,有些参数可以省略,函数自动使用其默认的参数。
int add(int a, int b = 1); //如果不输入b对应的参数,则默认b等于1
int x = 9, y = 10;
sum = add(x, y); //这是传统方式
sum = add(x); //后面一个参数没有输入,于是自动使用默认值b=1
注意:
①默认参数只在没有输入对应参数时发挥作用
②默认参数必须在参数表的右边
即:
int add(int a, int b = 1, int c = 2); //可以
int add(int a, int b = 1, int c); //错误!!!
函数重载(函数多态)
定义:可以定义、调用多个同名的不同函数。
理解:也就是说,我可以定义多个函数,它们函数名相同但是其内容不同。
引入“函数特征标”(function signature)概念: 函数特征标也就是函数的参数列表
函数重载的必要条件:这些同名函数的参数列表不同!
void print(char * str, int width); //①
void print(double d, int width); //②
void print(long d, int width); //③
void print(int i, int width); //④
void print(const char * str); //⑤
print ("Pancake", 15); //自动匹配调用了①
print ("Syrup"); //自动匹配调用了⑤
print (1999.0, 10); //自动匹配调用了②
print (1999, 12); //自动匹配调用了④
print (1999L, 15); //自动匹配调用了③
注意:
①:匹配时不区分const与非const变量,不区分类型引用与类型本身
②:和返回类型无关,特征标必须不同
函数模板
(一)
为什么c++要新增这样一个特性呢,带着问题出发。
试想这样一个简单问题:
我定义了这样一个函数
int function1(int a, int b)
{
int c = 2*a + b;
return c;
}
但我现在想解决两个问题:
int a, int b; // 想计算2*a + b
double c, double d; // 想计算2*c + d
难道复制function1的内容,然后把每个 int 换成 double ,另建一个函数?
NO!!!
c++增加了函数模板这个特性
template <typename AnyType> //template <class AnyType> 效果一样,class和typename都行
AnyType function1(AnyType a, AnyType b)
{
AnyType c = 2*a + b;
return c;
}
template <typename AnyType>
//这一句不能单独出现,其后面一行必须紧跟着函数声明或者函数定义
//template <typename XXXXX> 这里XXXXX是自己写的,其余的是固定搭配
看看具体的例子
template <typename T>
void Swap(T &a, T &b);
int main()
{
...
int i = 10;
int j = 20;
Swap(i, j);
double x = 24.5;
double y = 81.7;
Swap(x, y);
...
}
template <typename T>
void Swap(T &a, T &b)
{
T temp;
temp = a;
a = b;
b = temp;
}
注意:
函数模板的参数表并不要求全是模板参数类型,比如
template <typename T>
void Swap(T &a, T &b, int c); //可以有模板类型 T, 也可以有基本类型 int
(二)
虽然我们解决了上面提出的问题,但是我们是贪心的,这个函数模板仍然有局限性,就是:
比如我们定义了一个结构体:
stuct people
{
char name[10];
int age;
double weight;
}
我们现在依然想使用交换函数,但是只交换该结构体的 age 和 weight 项。
于是我们引入显性具体化模板函数
stuct people
{
char name[10];
int age;
double weight;
}
template <typename T>
void Swap(T &a, T &b, int c);
template <> void Swap<people>(people &p1, people &p2); //显示具体化模板函数
int main()
{
...
int i = 10;
int j = 20;
Swap(i, j);
people chen = {"chenjing", 24, 69};
people zhou = {"zhoudong", 24, 50};
Swap(chen, zhou); //由于其参数表,自动会匹配 显示具体化模板函数,而不是模板函数
...
}
template <typename T>
void Swap(T &a, T &b)
{
T temp;
temp = a;
a = b;
b = temp;
}
template <> void Swap<people>(people &p1, people &p2)
{
//此处代码交换p1、p2中的后两项内容
}
理解实例化与具体化,还没理解清楚,留作以后思考
(三)
再次贪心,思考这样一个问题
template <typename T1, typename T2>
void Swap(T1 x, T2 y)
{
???type xpy; //该用什么类型呢???
xpe = x + y;
}
int + double = double;
short + int = int;
所以在这个函数里面无法定义xpy的类型。
于是引入了关键字 decltype
int x;
decltype(x) y; //定义与 x相同的类型的变量 y
int x;
double y;
decltype(x+y) z; //定义与 (x+y) 相同的类型的变量 y
这样就完美解决了上述问题
template <typename T1, typename T2>
void Swap(T1 x, T2 y)
{
decltype(x+y) z; //解决问题
z = x + y;
}
这篇博客写的不错,挺满意!