高质量程序设计指南c++/c语言(32)--函数重载
出现在相同作用域中的两个函数,如果具有相同的名字而形参表不同,则称为函数重载。
任何程序都仅有一个main函数,main函数不能重载。
函数重载和重复声明的区别,如果两个同名函数声明的返回类型和形参表完全相同,则将第二个函数声明视为第一个的重复声明,一个函数声明多次是合法的,如:
void printValues(int i); void printValues(int i);
如果两个函数的形参表完全相同,但返回类型不同,则第二个声明是错误的,如:
void printValues(int i); int printValues(int i);
有些看起来不同的形参表本质上是相同的,如:
// each pair declares the same function Record lookup(const Account &); Record lookup(const Account &acct); //parameter names are ignored typedef Phone Telno; Record lookup(const Phone &); Record lookup(const Telno &); // Telno and Phone are the same type Record lookup(const Phone &, const Name &); Record lookup(const Phone &, const Name & = "hello"); // default argument does not change the number of parameters Record lookup(Phone); Record lookup(const Phone); // const is not irrevelant fot nonreference parameters
值得注意的是,形参与const形参的等价性仅适用于非引用形参。如果有const引用形参的函数与有非const引用形参的函数是不同的,指针与引用的情况相同。
1、重载与作用域
考虑下面的代码:
void print(const string &); void print(double); int main(void) { void print(int); //new scope: hides previous print print("hello"); print(10); //ok: print(int) is visible print(3.14); //ok: calls print(int) return 0; }
调用print时,编译器首先检查这个名字的声明,找到只有一个int型形参的print函数的局部声明。一旦找到这个名字,编译器将不再继续检查这个名字是否在外层作用域中存在,即编译器将认同找到的这个声明是程序需要调用的函数。余下的工作只是检查该名字的使用是否有效。在c++中,名字查找发生在参数类型检查之前。
2、实参类型转换
2.1 整数提升
void ff(int); void ff(short); ff('a'); //char promotes to int, so matches ff(int)
2.2 参数匹配和枚举类型
#include<iostream> using namespace std; enum Tokens { INLINE = 128, VIRTUAL = 129}; void ff(Tokens); void ff(int); int main(void) { Tokens curTok = INLINE; ff(128); //exactly matches ff(int) ff(INLINE); //exactly matches ff(Tokens) ff(curTok); //exactly matches ff(Tokens) return 0; }
2.3 const形参与函数重载
可基于函数的引用形参是指向const对象还是非const对象,实现函数的重载,指针与引用的情况相同。
//函数重载 void f(int *); void f(const int *); //重复声明 void f(int *); void f(int * const);