English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
يمكن تقسيم النماذج في C++ بشكل عام إلى فئتين رئيسيتين: الدوال النموذجية والفئات النموذجية. هذا المقال يكتب عن الدوال النموذجية، وسيعرض الفئات النموذجية لاحقًا.
التعريف: الدالة النموذجية هي وصف دالة عام، أي أنها تستخدم أنواع عامة لتعريفها، يمكن استبدال الأنواع العامة بأنواع محددة.
مثال على الكود:
#include <iostream> //إعلان الفئة النموذجية template<typename T> void Swap(T& a,T& b); int main() { int i = 10; int j = 20; std::cout << "i= " << i << ", " << "j= " << j; Swap(i,j);//توليد void Swap(int &,int&); std::cout << "i= " << i << ", " << "j= " << j; double x = 11.5; double y = 19.5; std::cout<<"x=" << x << "," << "y=" <<y; Swap(x,y); //يولد المحول void Swap(double &,double&); std::cout<<"x=" << x << "," << "y=" <<y; return 0; } //تعريف النمذجة template<typename T> void Swap(T& a,T& b) { T temp; temp = a; a = b; b = temp; }
هذا المثال هو أكثر أمثلة الدوال النموذجية بسيطة، حيث سيقوم الماكينيوم بحساب الدالة المناسبة بناءً على النوع المستخدم.
نماذج مكررة:
يمكن استخدام النماذج عند الحاجة إلى استخدام نفس الخوارزمية لمختلف الأنواع، مثل الكود المقدم أعلاه. ولكن ليس كل النوع يستخدم نفس الخوارزمية. للحصول على هذا الطلب، يمكن إعادة تعريف تعريف النماذج مثل إعادة تعريف تعريف تعريف الدوال العادية. يجب أن تكون خصائص جدول الدوال مختلفة مثل جدول الدوال العادية. مثال على الكود التالي:
#include <iostream> //إعلان الفئة النموذجية template<typename T> void Swap(T& a,T& b); const int iCount = 5; template<typename T> void Swap(T* a,T*b,int n); int main() { int i = 10; int j = 20; std::cout << "i= " << i << ", " << "j= " << j; Swap(i,j);//توليد void Swap(int &,int&) std::cout << "i= " << i << ", " << "j= " << j; double x = 11.5; double y = 19.5; std::cout<<"x=" << x << "," << "y=" <<y; Swap(x,y); //يولد المحول void Swap(double &,double&); std::cout<<"x=" << x << "," << "y=" <<y; int d[iCount] = {0,1,2,3,4}; int e[iCount] = {5,6,7,8,9}; Swap(d,e,iCount); //التطابق مع النموذج الجديد، لتبادل المجموعات return 0; } //تعريف النمذجة template<typename T> void Swap(T& a,T& b) { T temp; temp = a; a = b; b = temp; } template<typename T> void Swap(T* a,T*b,int n) { for (int i=0;i<iCount;++i) { T temp; temp = a[i]; a[i] = b[i]; b[i] = temp; } }
كما في الكود أعلاه، تم إضافة نموذج جديد لتبادل عناصر طريقتين، يتم تسمية السمة الأصلية للنموذج (T&،T&)، والسمة الجديدة للنموذج (T[],T[]),int). لاحظ أن في النموذج الثاني، نوع المعامل الأخير هو نوع محدد (int) وليس نوعًا عامًا، وليس بالضرورة أن تكون جميع معاملات النموذج هي معاملات نموذج.
التمثيل المحدد:
للمعاملات المحددة يمكن أن تكون هناك دوال غير النمذجة، نماذجية، وتمثيل محدد ونماذجية مولدة وكذلك نسخها المعدلة.
يجب أن تبدأ نماذج التمثيل المحدد والتعاريف بلغة template<>، وأن تشير إلى النوع من خلال الاسم.
التمثيل المحدد سيغطي النمذجة العادية، بينما ستغطي الدوال غير النمذجة التمثيل المحدد والنمذجة العادية.
كما يلي是非 نموذجية دالة لتغيير هيكل Job، نموذجية دالة وتمثيل مولد.
void Swap(job &,job&); //دالة غير النمذجة template <typename T> void Swap(T&،T&); //دالة النمذجة template <> void Swap<job>(job&،job&); //دالة التمثيل المحدد، يمكن إزالة اسم المعامل job بعد Swap، ويكون اسم الدالة template <> void Swap(job&،job&);
كما ذكر سابقًا، إذا كان هناك عدة نماذج، فإن المحول سيفضل النمذجة غير المحددة على النمذجة المحددة والنمذجة المحددة على النمذجة المولدة، بينما سيفضل النمذجة المحددة على النمذجة المولدة.
كما يلي النداء:
double u,v;
Swap(u,v); //استخدام النمذجة العامة
job a,b;
swap (a,b)//使用显示具体化版本。
实例化和具体化:
为了进一步了解模版,必须理解术语实例化和具体化。记住,在代码中包含函数模版本身并不会生成函数的定义,它只是一个用于生成函数定义的方案。编译器使用模版为特定类型生成定义时,得到的是模版实例(instantiation)。例如:函数调用Swap(i,j),使编译器生成一个Swap()的一个实例,该实例使用int类型。模版并非函数定义,但使用int的模版实例是函数定义。这种实例化方式被称为隐式实例化,因为编译器之所以知道需要定义,是由于程序调用Swap()时提供了int参数。
الآن يمكن للآلة السماح بالاستنساخ المحدد، مما يعني أن يمكنها الأمر مباشرة للآلة بإنشاء نموذج معين، مثل Swap<int>، ويكون النحو هو، النوع المحدد - يستخدم علامة <> لتحديد النوع، ويتم إضافة كلمة المفتاح template قبل التعبير:
template void Swap<int>(int, int);//الاستنساخ المحدد
الآلات التي تحقق هذا الخصائص ستجمع على هذه الطلبات لإنشاء نموذج Swap() من نوع int.
مختلف عن الاستنساخ المحدد، يستخدم الاستنساخ المحدد أحد التعبيرات التالية من الأثنين التاليين:
template <> void Swap<int>(int, int); template <> void Swap(int, int);
الفرق بين هذه الطلبات هو أن المعنى هو”لا تستخدم قالب Swap() لإنشاء تعريف الدالة، بل استخدم تعريف دالة مستقلة ومخصصة يتم عرضه كتعريف دالة من نوع int لإنشاء تعريف دالة.
النقطة الرئيسية هي أن استخدام نفس نوع التعبيرات المحددة والاستنساخ في وحدة برمجة واحدة سيؤدي إلى خطأ.
ما ذكرته أعلاه هو شرح مفصل لمظاهر قالب C++ الذي قدمته لك، آمل أن يكون مفيدًا لك. إذا كان لديك أي استفسارات، فلا تتردد في ترك تعليق.