7.8.4 实参类型转换
为了确定最佳匹配,编译器将实参类型到相应形参类型的转换划分等级。转换等级以降序排列如下:
(1)精确匹配(exact macth)。实参与形参类型相同。
(2)通过类型提升(promotion)实现的匹配。
(3)通过标准转换(standard conversion)实现的匹配。
(4)通过类类型转换(class-type conversion)实现的匹配。
2. 参数匹配和枚举类型
整数对象即使具有和枚举元素相同的值也不能用于调用期望获得枚举类型实参的函数。
虽然无法将整数值传递给枚举类型的形参,但可以将枚举值传递给整型形参。
3. 重载和const形参
仅当形参是引用或指针时,形参是否为const才有影响。
如果形参是普通的引用,则不能将const对象传递给这个形参。如果传递了const对象,则只有带const引用形参的版本才是该调用的可行函数。
如果传递的是非const对象,则上述任意一种函数皆可行。非const对象既可以用于初始化const引用,也可以初始化非const引用。但是,将const引用初始化为非const对象,需要通过转换来实现,而非const形参的初始化则是精确匹配。
对指针形参的相关处理如出一辙。可将const对象的地址值只传递给带有指向的const对象的指针形参的函数。也可将指向非const对象的指针传递给函数的const或非const类型的指针形参。如果两个函数仅在指针形参是否指向const对象上不同,则指向非const对象的指针形参对于指向非const对象的指针(实参)来说是更佳的匹配。
注意不能基于指针是否为const来实现函数的重载。当形参以副本传递时不能基于形参是否为const来实现重载。
7.9 指向函数的指针
int Method(int i, int j)
{
return i + 10 + j;
}
int (*MethodPointer2)(int i, int j);
int _tmain(int argc, char* argv[])
{
MethodPointer2 = Method;
cout << MethodPointer2(10, 20) << endl;
}
函数指针是指指向函数而非指向对象的指针。像其他指针一样,函数指针也指向某个特定的类型。函数类型由其返回类型以及形参表确定,而与函数名无关。
typedef int (*MethodPointer1)(int i);
int Method(int i)
{
return i + 10;
}
int _tmain(int argc, char* argv[])
{
MethodPointer1 m = Method;
cout << m(10) << endl;
}
1. 用typedef简化函数指针的定义
typedef int (*MethodPointer)();
2. 指向函数的指针的初始化和赋值
在引用函数名但又没有调用该函数时,函数名将被自动解释为指向函数的指针。
可使用函数名对函数指针做初始化或赋值。
直接引用函数名等效于在函数名上应用取地址操作符。
函数指针只能通过同类型的函数或函数指针或0值常量表达式进行初始化或赋值。
将函数指针初始化为0,表示该指针不指向任何函数。
指向不同函数类型的指针之间不存在转换。
3. 通过指针调用函数
指向函数的指针可用于调用它所指向的函数。可以不需要使用解引用操作符,直接通过指针调用函数。
如果指向函数的指针没有初始化,或者具有0值,则该指针不能在函数调用中使用。只有当指针已经初始化,或被赋值为指向某个函数,方能安全地用来调用函数。
4. 函数指针形参
函数的形参可以使指向函数的指针。这种形参有两种编写方式。
int Method(int i, int j)
{
return i + 10 + j;
}
int Method2(int i, int (*MethodPointer3)(int k, int j))
{
return MethodPointer3(i, 5);
}
int (*MethodPointer2)(int i, int j);
int _tmain(int argc, char* argv[])
{
MethodPointer2 = Method;
cout << Method2(10, MethodPointer2) << endl;
}
int Method1(int j(int i, int j)){}
int Method3(int(int i, int j)){}
5. 返回指向函数的指针
函数可以返回指向函数的指针,但是正确写出这种返回类型相当不容易。
允许将形参定义为函数类型,但函数的返回类型则必须是指向函数的指针,而不能是函数。
具有函数类型的形参所对应的实参将被自动转换为指向相应函数类型的指针。但是,当返回的是函数时,同样的转换操作则无法实现。
6. 指向重载函数的指针
C++语言允许使用函数指针指向重载的函数
指针的类型必须与重载函数的一个版本精确匹配。如果没有精确匹配的函数,则对该指针的初始化或赋值都将导致编译错误。