by Yazy -- 2005, 04.23 如果我们要实现一个支持多种输入类型的函数,在C++里我们可以 使用“重载”: void test(int n) { cout<<"test(int): "<<n<<endl; } void test(float n) { cout<<"test(float): "<<n<<endl; } void test(short n) { cout<<"test(short): "<<n<<endl; } 重载的思想是为每一种特定的类型去实现一个函数实体。这种方 式可能会给函数的使用者带来极大的便利,这种便利体现在用户 只须记住一个函数,而不必去为不同的类型选用其特定的函数调 用,因为“重载”的实现方式将这种“选择”定性地交给了编绎 器做了。所以“重载”是有助于用户使用函数来开发程序的,有 助于代码复用效率。 而重载的缺点是:它加重了函数开发者的开发负担。按“以用户 为中心”的思想,重载牺牲开发者更多的时间与精力,换来更多 的用户利益。函数作者需要负出更多的努力,体现于作者要写多 个版本的同一个函数;作者要保证函数的每一个版本都具有正确 或者通常是一致的语义。可能开发者要为这个保证负出更多,有 时候复杂的问题使得这种保证变得不那么有意义。 C++的template可以将要用到的类型泛化。比如在一个函数可能用 到一种未确知的类型 T,它可能是 int、float、short 或是某个 自定义类型。Template 可以让开发者使用这种“未知”,将这种 “未知”状态保留至函数被使用并且代码被编绎。 这种“未知” 的类型便是“泛化的类型”,使用这种编程范式的程序被称作“ 泛型程序”。 上面的 test 使用泛型编程方式来作便可能是: template<class T> void test(T n) { cout<<"template<class T> void test(T): "<<n<<endl; } 相比于“重载”,泛型的函数可以应用于更多的类型,甚至常常很难 确定它可以被用于多少种类型,而重载函数通常被使用于极有限数量 的类型。 泛型函数通常只要求输入类型符合某些特性,而不理会其具体是什么 类型。例如,某个泛型函数可能要求输入类型必须可以参加算术运算、 逻辑运算或是某种接口(例如 STL 里的 iterator)。 在C++里泛型还可以“泛”常数,即将“未知”状态赋予一种常数: template<class T, int SIZE> void test(T n) { int nums[SIZE]; //... cout<<"Size: "<<SIZE<<endl <<"Para: "<<n<<endl; } 泛型还包括:默认模板参数、特化等。有待学习……

|