لدينا IntArray فئة يوفر بديلا جيدا المدمج في مجموعة الأعداد الصحيحة. ولكن الحياة يمكن أن تأخذ صفائف مختلف أنواع البيانات. يمكننا أن نفترض, الفرق الوحيد بين عناصر الصفيف من نوع مزدوج من نوع البيانات في الإعلانات, باقي كود يطابق حرفيا.
لحل هذه المشكلة في c + + إليه قوالب. فئة ووظيفة الإعلانات المسموح باستخدام معلمات أنواع. اكتب معلمات يتم استبدال في وقت التحويل البرمجي هذه الأنواع, المدمج في أو معرفة من قبل المستخدم. يمكننا إنشاء قالب الفئة مجموعة, محل في الصف 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 نوع, المحددة في كل حالة. ولذلك, الإعلانات أعضاء أصبحت في الحالة الأولى من هذا النوع:
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; } |