我们IntArray班提供了一个很好的替代办法的内在的一系列整数. 但是生活中的阵列进各种数据类型. 我们可以假设, 唯一的区别之间的一系列因素的双重种类的我们是一类的数据在广告, 其他代码就是真的.
Для решения данной проблемы в С++ введен механизм 模板. В объявлениях классов и функций допускается использование 参数类型. 类型参数改为在编制时,这些类型, 内在的或用户规定的. 我们可以创造一个模板的一系列课, 替代课堂上IntArray内容类型int有关的一般类型参数. Позже мы конкретизируем 类型的各种备选案, 取代他们真的类型 int, 双倍 和 弦. 结果是将会使用这一说明所以, 如果我们实际上界定的三个不同类别,这三个数据类型.
现在可以改写作为一个模板的上课 阵列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
template <class elemType> class Array { public: explicit Array( int sz = DefaultArraySize ); Array( const elemType *ar, int sz ); Array( const Array &iA ); virtual ~Array() { delete[] _ia; } Array& operator=( const Array & ); int size() const { return _size; } virtual elemType& operator[]( int ix ) { return _ia[ix]; } virtual void sort( int,int ); virtual int find( const elemType& ); virtual elemType min(); virtual elemType max(); protected: void init( const elemType*, int ); void swap( int, int ); static const int DefaultArraySize = 12; int _size; elemType *_ia; }; |
关键字样板说, 这一套的模板, 参数的置于括号角 (<>). 在我们的案子只有一个参数elemType; 课程的关键词前面的其名字告诉, 什么这种办法代表了一种.
在具体说明的模板课程的一系列参数 elemType 取代的实际类型为每一个使用的, 如表中所示的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <iostream> #include "Array.h" int main() { const int array_size = 4; // elemType заменяется на int Array<int> ia(array_size); // elemType заменяется на double Array<double> da(array_size); // elemType заменяется на char Array<char> ca(array_size); int ix; for ( ix = 0; ix < array_size; ++ix ) { ia[ix] = ix; da[ix] = ix * 1.75; ca[ix] = ix + 'a'; } for ( ix = 0; ix < array_size; ++ix ) cout << "[ " << ix << " ] ia: " << ia[ix] << "\tca: " << ca[ix] << "\tda: " << da[ix] << endl; return 0; } |
它确定了三个例子课 阵列:
1 2 3 |
Array<int> ia(array_size); Array<double> da(array_size); Array<char> ca(array_size); |
什么的编译器, 如果你看到广告? 显示的案文的模板阵列, 将参数elemType的类型, 规定在每个案件. 因此,, ads成员在第一种情况下,这种:
1 2 3 |
// Array<int> ia(array_size); int _size; int *_ia; |
注意到, 它是什么完全符合该定义的联系 IntArray.
其余的两起案件,我们到了下列代码:
1 2 3 4 5 6 7 |
// Array<double> da(array_size); int _size; double *_ia; // Array<char> ca(array_size); int _size; char *_ia; |
会发生什么事的成员的职责? 这类参数elemType取的实际类型, 但是,编纂者没有具体规定的职能, 中没有援引任何地方的计划.
当你管理个方案这一事例会给下列结果:
1 2 3 4 |
[ 0 ] ia: 0 ca: a da: 0 [ 1 ] ia: 1 ca: b da: 1.75 [ 2 ] ia: 2 ca: c da: 3.5 [ 3 ] ia: 3 ca: d da: 5.25 |
该模版的引擎可用于继承的课程. 在这里的定义是一个模板的上课 ArrayRC:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#include <cassert> #include "Array.h" template <class elemType> class ArrayRC : public Array<elemType> { public: ArrayRC( int sz = DefaultArraySize ) : Array<elemType>( sz ) {} ArrayRC( const ArrayRC& r ) : Array<elemType>( r ) {} ArrayRC( const elemType *ar, int sz ) : Array<elemType>( ar, sz ) {} elemType& ArrayRC<elemType>::operator[]( int ix ) { assert( ix >= 0 && ix < Array<elemType>::_size ); return _ia[ ix ]; } private: // ... }; |
替代实际参数而不是 类型参数elemType 发生在该基地, 和源类别.
1 |
ArrayRC<int> ia_rc(10); |
定义的行为完全相同的, 作为的定义 IntArrayRC 从前科. 变化的例子使用情况的前一节.
1 |
swap( ia1, 1, ia1.size() ); |
首先, 去 оператор // 职能 换() 还有你应该做出有效的模板, 我们将需要采用一个功能 换() 模板.
1 2 3 4 5 6 7 8 9 |
#include "Array.h" template <class elemType> inline void swap( Array<elemType> &array, int i, int j ) { elemType tmp = array[ i ]; array[ i ] = array[ j ]; array[ j ] = tmp; } |
每个电话交换() 产生适当的规格, 这取决于种种. 这就是计划, 使用模板 阵列 和 ArrayRC:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include <iostream> #include "Array.h" #include "ArrayRC.h" template <class elemType> inline void swap( Array<elemType> &array, int i, int j ) { elemType tmp = array[ i ]; array[ i ] = array[ j ]; array[ j ] = tmp; } int main() { Array<int> ia1; ArrayRC<int> ia2; cout << "swap() with Array<int> ia1" << endl; int size = ia1.size(); swap( ia1, 1, size ); cout << "swap() with ArrayRC<int> ia2" << endl; size = ia2.size(); swap( ia2, 1, size ); return 0; } |