3 - الباني والتحميل الزائد Overloading Constructors

الباني والتحميل الزائد Overloading Constructors

يمكن أن نجري تحميلا زائدا للبانيات في نفس الصنف مثلما كنا نفعل مع التوابع، فكنا نستطيع أن نكتب عدة توابع بنفس الاسم مختلفة بين بعضها بسلسلة الوسطاء من ناحية العدد أو النمط أو الترتيب. حيث ينفذ المترجم نسخة التابع المطابقة للتابع المستدعى من ناحية سلسلة الوسطاء. وكذلك في حالة الباني، فسينفذ المترجم نسخة الباني التي تأخد سلسلة وسطاء تطابق ما نستدعيه عند إنشاء كائن من الصنف المعني.
لو أننا عرفنا صنفا ما بدون تحديد أي بان له، فسيفترض المترجم تلقائيا وجود بانيان وهما: الباني الافتراضي default constructor، والباني الناسخ copy constructor. مثال:
كود:
كود:
 	class CExample { public: int a,b,c; void multiply (int n, int m) {a=n; b=m; c=a*b; }; };
لا يحوي هذا الصنف أي باني بشكل صريح، لكن المترجم سيفترض مباشرة وجود البانيين التاليين فيه:

باني افتراضي فارغ:

وهو باني لا يأخذ وسطاء ولا يحوي تعليمات تنفيذية (nop) أي لا يقوم بأي عمل.
كود:
كود:
CExample::CExample() {};
بان ناسخ:

وهو بان بوسيط واحد من نفس نمط الصنف وينسخ قيمة كل حقل غير ثابت (nonstatic) من الوسيط الممرر إلى حقول الكائن الحالي:
كود:
كود:
 	CExample::CEample (const CExample &rv) { a=rv.a; b=rv.b; c=rv.c; }
يجب الانتباه بشدة إلى أننا سنجد البانيين الافتراضيين (الباني الفارغ والباني الناسخ) فقط في حال عدم تعريف أي باني آخر بشكل صريح للصنف، أما إن وجد أي باني يأخذ أي نوع من الوسطاء فلن نجد أيا من هذين البانيين الافتراضيين. فإذا أردت المحافظة عليهما بعد ان تُعرف أي بان لصنفك، فعليك إعادة كتابتهما.

إذاً وكما قلنا، نستطيع إجراء تحميل زائد للبانيات بكتابة عدة بانيات لنفس الصنف بحيث يختلف كل منهما عن البقية بسلسلة وسطائه. مثال:
كود:
كود:
 	// overloading class constructors #include <iostream.h>  class CRectangle {  int width, height; public: CRectangle(); CRectangle (int,int); int area (void) {return (width*height);} };  CRectangle::CRectangle() { width=5; height=5; }  CRectangle::CRectangle (inta, int b) { width=a; height=b; }  int main() { CRectangle rect (3,4); CRectangle rectb; cout<<"rect area:"<<rect.area()<<endl; cout<<"rectb area:"<<rectb.area()<<endl; }  
كود:
Output:  rect area:12 rectb
area:25 لقد صرحنا في هذا المثال عن الكائن rectb بدون استخدام أي وسيط، بالتالي سيستدعى الباني الأول الذي ليس له وسطاء ويضع في الحقلين width و height القيمة 5. وتستطيع الملاحظة أننا لم نضع قوسين صغيرين () فارغين عند استخدام الباني بدون وسطاء:
كود:
كود:
 	CRectangle rectb; // right CRectangle rectb(); // not preferred!