您的位置:首页 > 编程语言 > C语言/C++

对C++模板的新认识

2009-01-16 08:57 232 查看
C++的模板,是面向对象多态性的方面之一。泛型编程一般指用模板来进行程序设计。在C#2.0中,引入了泛型的概念,它比C++有更好泛型支持,无论是在语言的语法上,还是在程序生成的代码上。

上个学期,老师讲到模板的时候,全班人都一头雾水。大家都只知道模板的一个最重要的作用:使一个类或一个函数支持多种数据类型。举个简单的例子,在对数据进行排序时,需要进行比较,如果发现顺序不符合要求,就要进行数据交换。在用模板之前,我们会用下面的代码:

void swap(int a,int b){
  int temp = b;
  b=a;
  a=temp;
}

果要交换的是double型数据或者其他数不清的数据,那么上面的代码就不适用。C++支持的函数重载可以让我们定义同名的函数,通过不同的函数签名,C
++可以自动判断应该执行哪一个函数,如果要交换的数据是double型,那么利用函数重载的方法,我们会多写下面的代码:

void swap(double a,double b){
  double temp = b;
  b=a;
  a=temp;
}

们会看到,两种之间的代码差别十分之小。我们所做的改变就是把int改为double.那么如果是其他数据类型呢,如char,还有用户自己定义的类或结
构呢。如果我们用这样的方法,后果会相当严重。有两种分法可以解决。一种是空指针,函数的参数都为空指针,那么数据的交换就是交换指针的地址。这种方法在
C语言中很普遍。另一种就是使用模板。如果我们用模板,会有下面的代码:

template<class T>
void swap(T a,T b){
  T temp = b;
  b=a;
  a=temp;
}

做的改变还是很少。但却实现了我们上述的要求。然而,空指针与模板之间最大的差别应该是在程序代码生成。模板是属于编译时多态性。即它的多态时是在代码编
译的时候已经确定下来。如果上面那段模板代码在程序设计时使用了许多次,其中处理的数据类型有n种,那么在编译出来的代码中,就会产生n个swap函数,
分别对应你在程序中的每一个数据类型。如果对许多种数据类型进行交换,那么程序编译出来的体积将会很膨胀。对于空指针来说,代码是相当简洁。现在我们就能
解释一下模板的语法了。我们编写一个简单的模板类:

template<class T>
class A{
private:
  T value;
public:
  A(T);
  T GetValue();
  void SetValue(T);
};
这是模板类A的界面,上面的代码仅仅声明了它的私有成员和公共的构造函数和方法,并没有实现的代码。C++提倡界面与实现相分离,我也喜欢这么做,下面是实现的代码:

template<class T>
A<T>::A(T t){
  value = t;
}

template<class T>
T A<T>::GetValue(){
  return value;
}

template<class T>
void A<T>::SetValue(T t){
  value = t;
}
初看一下,会觉得罗索,因为每个构造函数和方法的实现代码都要template的字样,但如果不这么做,编译器不知道如何编译。


果上面的代码用在int上,那么编译器把每个T换成int,假设它把tempalte<class
T>和<T>都去除了,那么我就就定义保存一个整数的类。如果在程序中还把上面的类用在double上,那么编译器会对上面的代码进行
复制,并T改为double,重复收尾操作,就会得到一个保存double的类。这样,你会很清楚为什么每个方法的实现都要template了。因为类是
一个模板类,要为模板类实现它的方法,我们就得写模板函数。附加template为的就是在编译时,每个类都有相应的方法实现代码,同时编译器知道如何去
构造每个类的实现代码。

今天一整天都在跟模板打交道。语言还是要在实践上学习。上个学期,知道了什么是抽象类,模板,模板的继承等等。
今天为了实现让图这个数据结构支持各种数据。我写了三百多行代码来构造一有向图。效率很低,因为但抽象类和模板的比较复杂的应用不熟,debug也花了许
多时间,期间还问一些师兄。不过经过这么一次,对模板和抽象类的认识又加深了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: