C++的抽象能力在各种语言中算得上出类拔萃的。正如大地是Titan的力量之源,C++的抽象能力也有它的技术基础。
泛型编程可以算作最重要的C++特性。在“C With Class”时代,C++等抽象能力相比SmallTalk之类的OOP语言,并没什么过人之处。但在应用的刺激下(最早是io stream),C++引入模板,以实现参数化类型的需求,也就是“泛型”的功能。然而,C++革命性的进步得益于Alexander Stepanov在STL上所做的贡献。
泛型提供了一种“泛化”编程手段。在泛型编程中,我们被赋予了一种面向一类问题,而非单个的具体问题,的编程能力。然而,仅仅“泛化”,还不足以提供充分的抽象能力。实际上,C++的独特,而又强大的抽象能力,来源于两个相对的概念:泛化和特化。
泛化,可以看作处理具备某种特征的一类类型的能力。而特化,则是一个相反的过程:处理一个具体的问题。
如同道家的阴阳变化造就世间万物,泛化和特化的有机组合,构成了C++的抽象体系。可以通过一个简单的(已经被用烂的)例子演示这种组合:
void swap(int& a, int& b) {
int t=a;
a=b;
b=t;
}
函数swap交换两个int类型变量的值。考虑到类型无穷无尽,不可预测(谁知道swap的使用者会创造除什么类型进行交换)。所以,为了避免无穷无尽的“来料加工”,我们必须创建一个对任何类型都有效的算法。于是,模板出现了:
//代码#1
template<typename T>
void swap(T& a, T& b) {
T t(a);
a=b;
b=t;
}
泛化展示出了它的威力:写一次代码,套所有类型(当然得符合要求:可以赋值,拥有复制构造函数)。
但事情并没有完结。对于某些类型,这个swap模板是个着实笨拙的算法。比如matrix:
matrix a,b;
swap(a,b);
此时swap的代码等价于这样一个函数:
//代码#2
void swap_matrix(matrix& a, matrix& b) {
matrix t(a);
a=b;
b=t;
}
这里会产生至少一个临时变量,并且伴随着大量的数据拷贝。对与C++的使用者而言,这是邪恶的犯罪行为。现在,假设