事物总有优、劣两面性,不可能事事完美,所以必须权衡和取舍。
编程语言设计就是这样。
弱类型语言的编译器可以自动推断类型,不必由程序员事先声明。这样的语法机制学习简单,语言表达简单易懂,代码更优雅,开发周期更短,更加偏向逻辑设计。但是,变量混乱,运行效率低下,更容易出BUG,难以调试。
相反强类型语言,对于类型和存储的约束使得学习成本上升,开发效率比较低下,代码设计必须考虑存储问题,但是程序可靠,调试简单,变量更加规范。
所以强类型语言就要考虑相同功能的函数(按道理应该取同样的函数标识符)因为参数类型不同而要考虑标识符重用,其语言机制就是函数重载,只要参数类型不同或者参数个数不同,就可以使用相同的函数名,编译器可以按参数的不同而调用不同的版本。
但如果站在代码重用的角度考虑,函数重载还是没有解决代码冗余的问题。因为重载的函数除了类型不同以外,剩下的函数名和函数体基本一样。这就是C++语言类型泛化的语法机制,用函数模板通过参数泛化在函数调用时由编译器去生成不同参数的函数。
1 函数重载
对于功能相同,只是参数不同的函数似乎可以通过一个条件判断(判断参数差异)来调用不同定义的函数,而其实这完全可以由编译器来完成,这就是函数重载的语法机制。
// Using overloaded functions #include <iostream> using std::cout; using std::endl; int max(const int data[],const int len); // Prototypes for long max(const long data[],const int len); // a set of overloaded double max(const double data[],const int len); // functions int main() { int small[] = {1, 24, 34, 22}; long medium[] = {23, 245, 123, 1, 234, 2345}; double large[] = {23.0, 1.4, 2.456, 345.5, 12.0, 21.0}; const int lensmall = 4; const int lenmedium = 6; const int lenlarge = 6; cout << endl << max(small, lensmall); cout << endl << max(medium, lenmedium); cout << endl << max(large, lenlarge); cout << endl; std::cin.get(); return 0; } // Maximum of ints int max(const int x[],const int len) { int maximum = x[0]; for (int i=1; i < len; i++) if(maximum < x[i]) maximum = x[i]; return maximum; } // Maximum of longs long max(const long x[], const int len) { long maximum = x[0]; for (int i=1; i < len; i++) if(maximum < x[i]) maximum = x[i]; return maximum; } // Maximum of doubles double max(const double x[], const int len) { double maximum = x[0]; for (int i=1; i < len; i++) if(maximum < x[i]) maximum = x[i]; return maximum; }
输出:
34 2345 345.5
相同功能的函数应使用相同的函数标识符,函数重载的语法解决了函数重名的问题,但相似函数体的代码重用的问题还需要函数模板来解决。
2 函数模板
上述代码冗余的问题似乎在代码复制时用查找、替换就可以完成重载函数的定义,而这恰恰是编译器所擅长的工作。
函数模板语法机制就是通过类型泛化由编译器生成具体参数类型不同的重载函数版本。
// Using function templates #include <iostream> using std::cout; using std::endl; // Template for function to compute the maximum element of an array template<typename T> T max(const T x[], const int len) { T maximum = x[0]; for(int i=1; i < len; i++) if (maximum < x[i]) maximum = x[i]; return maximum; } int main() { int small[] = { 1, 24, 34, 22}; long medium[] = { 23, 245, 123, 1, 234, 2345}; double large[] = { 23.0, 1.4, 2.456, 345.5, 12.0, 21.0}; const int lensmall = 4; const int lenmedium = 6; const int lenlarge = 6; cout << endl << max(small, lensmall); cout << endl << max(medium, lenmedium); cout << endl << max(large, lenlarge); cout << endl; std::cin.get(); return 0; }
完全相同的输出:
34 2345 345.5
-End-