3.5 内联函数和重载函数

内联函数是C++语言为降低小程序调用开销而采取的一种机制。

函数重载是指以同一个名字命名多个函数实现版本。重载函数是一种简单的多态形式。

3.5.1 内联函数

函数调用时,需要建立栈空间来保存调用时的现场状态和返回地址,并且进行参数传送,产生程序转移。系统完成这些工作都需要时间和空间方面的开销。因此,C++提供内联函数机制,定义一些功能比较简单、代码比较短的函数。编译时,系统把内联函数的函数体嵌入到每一个函数调用处,节省了程序运行时的调用开销。

定义内联函数的方法是,在函数名第一次出现时,在函数名之前冠以关键字 inline。通常在函数原型中指定。若已在函数原型中指定inline,则函数定义时不能重复给出。

内联函数原型为:

            inline  类型  函数名  (形式参数表);

内联函数的调用方法与其他普通函数相同。

【例3-27】从键盘输入一串字符,以回车结束,统计其中数字字符个数。

            #include<iostream>
            #include<cstdio>
            using namespace std;
            inline int isnumber(char);
            int main()
            {  char c;
              int n;
              n = 0;
              while((c = getchar()) != '\n')
                  if(isnumber(c))  n++;
              cout << "n = " << n << endl;
            }
            int isnumber(char ch)
            {  return(ch>='0'&&ch<='9')?1:0;  }

对内联函数的使用需要说明如下3点。

① 若inline不在函数名第一次出现时指定,则编译器把它作为普通函数处理。

例如,若例3-27的isnumber函数写成:

            int isnumber(char);
            //…
            inline int isnumber(char ch)
            {  return(ch>='0'&&ch<='9')?1:0;  }

则isnumber函数是普通函数,编译器不作嵌入处理。

② 一般内联函数只适合于1~5行的小程序。在内联函数中,不能含有复杂的流程控制语句。例如,不能含有多分支语句和循环语句,否则,inline无效。

③ 递归函数不能说明为内联函数。

3.5.2 重载函数

为函数命名时,程序员总希望“见名知义”。但有时“义”相同的任务处理的数据对象类型、数量不同,实现的代码也有区别。C++语言允许定义多个同名函数,各个函数有不同的参数集,这些函数称为重载函数。编译器根据不同参数的类型和个数产生调用匹配。函数重载常用于生成几个类似任务而处理不同数据个数、类型的同名函数。

【例3-28】编写重载函数,求两个或三个整数的最大值。

            #include<iostream>
            using namespace std;
            int max(int, int);
            int max(int, int, int);
            int main()
            {  cout<<max(5,3)<<endl;
              cout << max(4, 8, 3) << endl;
            }
            int max(int a, int b)
            {  return a>b?a:b;  }
            int max(int a, int b, int c)
            {  int t;
              t = max(a, b);
              return max(t, c);
            }

C++编译器只根据函数参数表(参数类型和个数)进行重载版本的调用匹配,函数返回值的内容不起作用。例如:

            int average(int, int);
            double average(int, int);

这两个不是重载函数,C++编译器认为函数重复说明。

另外,要注意重载函数中使用默认参数时可能产生的二义性。例如,若max重载函数定义为:

            int max(int, int);
            int max(int, int, int = 0);

则调用 max(5, 3)

无法选择调用版本。