[email protected] . جامعة الكوفة/ نضال خضير العبادي.د void indata ( int a ) ; { value2 = a ; } void display ( void ) { cout << value2 << \" \\n \" ; } friend void exchange ( Class-1 & ، Class-2 & ) ; }; void exchange ( Class-1 &x ، Class-2 &y ) { int temp = x.value1 ; x.value1 = y.value2 ; y.value2 = temp ; } main () { Class-1 C1 ; Class-2 C2 ; C1.indata ( 100 ) ; C2.indata ( 200 ) ; Cout << \" values before exchange : \" << \" \\n \" ; C1.display() ; C2.display() ; exchange ( C1 ، C2 ) ; Cout << \" values after exchange : \" << \"\\n \" ; C1.display() ; C2.display() ; return 0; } 9.24 مطرجا البرنامج Values before exchange : 100 200 455
من البداية إلى البرمجة الكيانيةC++ Values after exchange : 200 100 • برنامج لايجاد مجموع مربع عددين باستخدام الدوال الصديقة // Example 9.15 #include <iostream> class Cal { float x َ y; public: void set (float a َ float b); friend float sqsu (Cal triangle); }; void Cal::set (float a َ float b) { x = a; y=b; } float sqsu (Cal tri) { return tri.x*tri.x + tri.y*tri.y; } int main() { Cal shape; shape.set(12.25, 6.80); float w=sqsu(shape); cout<<\"\\nThe square sum of is \"<<w<<endl; return 0; } 456
د .نضال خضير العبادي /جامعة الكوفة [email protected] . 9.17الاوناف الصديقة Friend Classes الصنف من الممكن ان يكون صنف صرديق لصرنف أخرر .وعنردما تكرون هرذ الحالة ،فران الصرنف الصرديق وكرل دوالرة الاعضراء يمكنهرا الوصرول الرى الاعضراء الخاصة المعرفة مع الصنف الأخر. ملاحظة //: بالامكان ان تعلن عن كرل الردوال الاعضراء لصرنف معرين كردوال صرديقة لصرررنف اخرررر ،وفررري هرررذ الحالرررة فررران الصرررنف يررردعى ( صرررنف صررررديق ) ) ( friend classوهذا ممكن ان يعلن عنه كمايأتي { class Z ………….. ; } ; friend class X هنرا كرل الردوال الاعضراء فري الصرنف ) (Xسرتكون دوال صرديقة فري الصنف )(Z الامثلة اللاحقة توضح طريقة استخدام الصنوف الاصدقاء. • برنامج لايجاد مجموع عددين بعد عكس اشارتهما // Example 9.16 >#include <iostream { class OpVal ;float x َ y public: )OpVal (float a َ float b } ;{ x = -a; y = -b ;friend class Abso ;} 457
من البداية إلى البرمجة الكيانيةC++ class Abso { public: float AddVal (OpVal z ); }; float Abso::AddVal(OpVal z ) { return (z.x + z.y); } int main() { float x َ y; cout<<\"Enter two values: \"; cin>>x>>y; OpVal p (x َy); Abso q; cout<<x<<\" and \"<<y<<\" processed: \"<<q.AddVal(p); return 0; } • برنامج لعرض اس الب مع درجتة // Example 9.17 #include <iostream> #include <cstring> class Student { char name[30]; public: void putname(char *str); void getname(char *str); 458
[email protected] . جامعة الكوفة/ نضال خضير العبادي.د private: int grade; public: void putgrade (int g); int getgrade(); }; void Student::putname(char *str) { strcpy(name َstr); } void Student::getname (char *str) { strcpy(str َname); } void Student:: putgrade(int g) { grade = g; } int Student::getgrade() { return grade; } int main() { Student x; char name[50]; x.putname(\"Taqwa Zaid\"); x.putgrade(5); x.getname(name); cout<<name<<\" got \"<<x.getgrade()<<\" from OOP.\"<<endl; return 0; } • برنامج لايجاد العدد الاوغر بين عددين // Example 9.18 459
C++من البداية إلى البرمجة الكيانية >#include <iostream { class Nums ;int a َb public: ;)(void read ;)(int min ;} { )(inline void Nums::read ;int i َj ;\" cout<<\"\\nType two numbers: ;cin>>i>>j ;a=i; b=j } )(inline int Nums::min } ;{ return a < b ? a:b { )(int main ;Nums ob ;)(ob.read ;)(cout<<\"\\nThe smaller value was :\"<<ob.min ;return 0 } الان سنحاول كتابة برنامجا بسيطا وسنجزأ كتابترة علرى شركل مراحرل لنكتبهرا واحردة بعرد الاخررى وسريكون مفيرد جردا اذا مرا جلسرت خلرف الحاسربة وكتبرت هرذا البرنامج مرحلة بعد الاخرى .في كل مرحلة سوف لاتبدأ من جديد وفري كرل مرحلرة 461
د .نضال خضير العبادي /جامعة الكوفة [email protected] . سرتكون هنرا معلومرة اضرافية ،بعضرها اضرافات بسريطة او صرغيرة وفري كرل مررة سيتم شرا المرحلة لتتابع معنا البرنامج. • البرنامج هو من برامج التسلية وهو مخص للعب الور بالحاسوأ. • المرحلة الاولى البرنرامج ممكررن ان لايكرون بسرريطا .سريعر البرنررامج لاشريء ،ولكررن يررتم ترجمتة ،ويمكنك البدء مع اقل عدد من عبارات البرنامج التي من الممكن ترجمتها: // Stage #1 class CardDeck { ;} )(void main { } • المرحلة الثانية فري المرحلرة الثانيرة يرتم اضرافة الكلمرات المفتاحيرة ( ،)public ،privateلغايرة الان هذ الكلمات لامعنى لها وذلك لعردم وجرود اي شريء ممكرن ان يكرون خراص او عام .القصد من هذا هو خلق عادات او تقاليرد جيردة .واحردة مرن هرذ العرادات الجيردة هو البدء مع هيكل فار ينبهك لاستخدام مقاطع عامرة وخاصرة .هرذ المرحلرة ايضرا تخلق مخرجات قليلة ،والتي تجعل البرنامج اكثر قابلية للتنفيذ .وخطوة مهمرة اخررى في هذا البرنامج هو انك تلاحظ كيف اصبح لديك كيران فري هرذ المرحلرة .لاحرظ ان المعرف ( )Dهو كيان ،وان المعرف ( )CardDeckهو صنف .ان العبارة البرمجيرة (; )CardDeck Dهي الاعلان عن الكيران .Dهرذ المرحلرة هري عمليرة اكثرر ،وفيهرا مخرجات لكنها تبقى في الحد الادنى مع ان البرنامج اصبح اكثر هيكلية. // Stage #2 > #include <iostream 461
C++من البداية إلى البرمجة الكيانية > #include <conio class CardDeck { private: public: ;} {)(void main ;)(clrscr ;cout << \"CARD DECK PROGRAM STAGE #2\" << endl ;CardDeck D ;)(getch } ملاحظة//: بالنسربه للردوال الكبيررة (التري تحتراج الرى اكثرر مرن سرطر لكتابتهرا) ،اذا مرا وضعت داخل تعريف الصنف اي داخل جسم الصنف ممكن ان يقود الى تعريرف صنف كبير جدا ،ولمنع ذلك ،فان C++يسمح لك من تعريف الدوال خارج جسرم الصرنف .الردوال التري تعررف خرارج الصرنف يقرال لهرا دوال خارجيرة ).(outline هررذا المصررطلح يعنرري انرره عكررب الرردوال الداخليررة ) (inlineوالترري تعرررف داخررل الصنف. • المرحلة الثالثة في المرحلة الثالثة فانك ستفكر في البيانات التري تحتاجهرا للخرزن فري الصرنف ) .)CardDeckالقرررار هررو ان تخررزن عرردد الطرراولات ( )decksوسرريكون بررالمتغير ) ,)NumDeckوعدد لاعبري الرورق ويخرزن برالمتغير ( )NumPlayersوعردد اوراق 462
د .نضال خضير العبادي /جامعة الكوفة [email protected] . اللعب التي تعطى لكل لاعب وسرتكون برالمتغير ( )CardsDealtوعردد الاوراق التري تتر على الطاولة او الطاولات وتكون بالمتغير ( ،)CardsLeftومن الممكن اضافة متغيرررات اخرررى لخررزن معلومررات مفيرردة ،ولكررن مررع هررذا البرنررامج سررتكون هررذة المعلومات كافية ،هدفنا هو ان تتعلم البرمجة الكيانية ،وليب لعب الورق!. هنا اسماء برمجة كيانية عامرة لهرذ المعرفرات الاربرع وضرعت فري الصرنف ( .)CardDeckان حقررول البيانررات الترري تخررزن معلومررات الصررنف ترردعى صررفات ( )attributesللصنف. في هذ المرحلرة ستضراف بيانرات اعضراء خاصرة للصرنف وهرذ هري صرفات الصنف CardDeck // Stage #3 > #include <iostream > #include <conio class CardDeck { private: ;int NumDecks ;int NumPlayers ;int CardsLeft ;int CardsDealt public: ;} )(void main { ;)(clrscr ;cout << \"CARD DECK PROGRAM STAGE #3\" << endl ;CardDeck D ;)(getch 463
C++من البداية إلى البرمجة الكيانية } • المرحلة الرابعة لاتتعجب اذا لم تقم دالة البناء بقرع الجرس اطلاقا ،فهرذ بشركل كامرل مفراهيم جديردة لرم توضرح براي مرن البررامج السرابقة ،فالرذين لرديهم الفرة مرع البرمجرة الكيانيرة سيستغربون من حذف واحد من مكونات الصنف المهمة مثل دالة البنراء .حسرنا ،لقرد كان ذلك مقصودا ،لاني اشعر برغبة لاعطاء المعلومة على شركل جرعرات صرغيرة تساعد علرى فهمهرا مثلمرا عمليرة اطعرام طعرام علرى شركل لقيمرات صرغيرة فراذا كانرت اللقمة كبيرة جدا فانها ربما تؤدي الى الاختناق ولاتنزل الى المعدة. الكيانات تهدف الى جعل البررامج اكثرر اعتماديرة .واحردة مرن المشراكل العامرة في البرمجة الكيانية هي تلرف او تحطرم البرنرامج بسربب ان هياكرل البيانرات المختلفرة لاتستلم المعلومة المناسبة .في العديد من الحرالات مثرل تحطرم او تلرف البرنرامج كران من الممكن ان يرتم منعهرا اذا مرا ترم ابترداء او انشراء معلومرات هياكرل البيانرات بشركل مناسب ،وهذ هي مهمة دالة البناء لابتداء الكيان بشكل مناسب خلال مرحلة الخلق، ويمكن ان يكون هذا ايضا خلال فترة بناء او تكروين الكيران .ان دالرة البنراء هري دالرة صنف عامة محددة ،ودالة البناء يتم استدعااها اليا في عبرارة البرنرامج التري تعررف الكيران .بكرلام اخرر ،فري مرحلرة تكروين الكيران ،دالرة البنراء تسرتدعى والكيران ينشرأ. تحتاج ان تنمر الى موقعين لفهم عمل دالة البناء ،فهنا دالرة بنراء فري الاعرلان عرن الصنف وهنا تنفيذ لدالة البناء كما سربق ووضرحنا .ان الغرر مرن دالرة البنراء هرو لابتداء الصنف اي اسناد القيم الابتدائية للصنف. // Stage #4 >#include <iostream >#include <conio class CardDeck { private: 464
د .نضال خضير العبادي /جامعة الكوفة [email protected] . ;int NumDecks ;int NumPlayers ;int CardsLeft ;int CardsDealt public: ;) ( CardDeck // constructor ;} )(void main { ;)(clrscr ;cout << \"CARD DECK PROGRAM STAGE #4\" << endl ;CardDeck D } ) (CardDeck::CardDeck // constructor { ;cout << endl << endl ;cout << \"CONSTRUCTOR CALL\" << endl ;NumDecks = 1 ;NumPlayers = 1 ;CardsLeft = NumDecks * 52 ;CardsDealt = 1 ;)(getch } مرن السرهولة تعريرف دالرة البنراء فري الصرنف .ان رأس دالرة البنراء هرو اسرم الصنف نفسره بردون ) ،)voidوايضرا بردون عبرارة الارجراع (او اي شريء يشرير الرى اسم دالة البناء على انه متغير كما في الدوال الاعتيادية) .تقليديا ،دالة البناء هي اول دالة عضو توضع في المقطع العام ) .)publicدالة البنراء يجرب ان تكرون فري المقطرع 465
C++من البداية إلى البرمجة الكيانية العرام للصرنف .ان تنفيرذ دالرة البنراء العضرو هرو الرى حرد مرا غيرر اعتيرادي ،فكرل مرن معرف الصنف اسمة ) )CardDeckوكذلك معرف الحقل اسمة ) ،)CardDeckوهرذا يعنري ان الدالرة ) )CardDeckتوجرد فري الصرنف ) .)CardDeckوهرذا غريرب بعرض الشريء ،ولكرن يجرب ان تعمرل بثقرة وابترداء .ان اسرتخدام اسرم الصرنف لهرذ الدالرة العضو المميزة يعني ان الدالة سوف تستدعى اليرا خرلال مرحلرة تكروين كيران جديرد. لاحظ ،ليب جيدا كفاية لخلرق دالرة تقروم بابترداء كيران مرا .فيجرب عليرك ان تتاكرد مرن استدعاء الدالة .ان اعطاء اسرم للدالرة ليكرون نفرب اسرم الصرنف هري التري يممرن بهرا C++استدعاء دالة البناء. ان دالرة البنراء فري الصرنف ) )CardDeckتتضرمن عبرارة اسرتدعاء دالرة البنراء ) .)CONSTRUCTOR CALLوهذ ليست عادة او تقليد عام في دالة البناء .ولكنهرا مفيدة في هذا المثال وذلك لانها توضح لك متى يتم استدعاء دالة البنراء .اسرتمر ونفرذ البرنامج .متى بالضبط سيتم استدعاء دالة البناء؟ سوف تلاحظ ايضا ان الابتداء في دالة البناء يعمرل عردد مرن الفرضريات ,فهرو يفترر ان كرل لعبرة ورق فري البرنرامج تتطلب على الاقل طاولة واحدة ,وهي تفتر ان كل لعبة ورق في البرنامج تحتراج على الاقل طاولرة واحردة ،كرل لعبرة فيهرا علرى الاقرل لاعرب واحرد ،وهنرا 52ورقرة على الطاولرة ،وعلرى الاقرل ورقرة واحردة موجرودة فري كرل يرد .غالبيرة العراب الرورق ربمرا تحتراج الرى قريم مختلفرة ،هرذا جيرد وبعرض بررامج اللعرب مرن الممكرن ان تخلرق دوال مناسربة للتنبيرة الرى القريم الضررورية .مرن اجرل التهيئرة للبردء فران الاختيرارات السابقة تفي بالغر . • المرحلة الخامسة حان الوقت لاضافة دوال اعضاء الى الصنف لعمل شيء ما .كل البيانات فري الصنف ) )CardDeckهي خاصرة ولايمكرن الوصرول لهرا بشركل مباشرر .تحتراج الرى دوال اعضراء يمكنهرا الوصرول الرى البيانرات وتمهرر لرك محتوياتهرا .دوال الصرنف الاعضراء ترردعى ايضرا ( .)actions or methodsفكرر فرري الصررفات ()attributes كاسماء وفكر في ( )actionكافعال. 466
[email protected] . جامعة الكوفة/ نضال خضير العبادي.د لغايرة مرا فران الفعرل الوحيرد الرذي نرغرب بره هرو اظهرار قريم كرل واحردة مرن هرذا يكرون بطريقرة.)CardDeck) ) (او البيانات الاعضراء) فري الصرنفattributes) .سبق ان رايتها في برامج سابقة .هنا سيتم اضافة دوال اعضاء عامة لعر البيانات الخاصة // Stage #5 #include <iostream> #include <conio> class CardDeck { private: int NumDecks; int NumPlayers; int CardsLeft; int CardsDealt; public: CardDeck(); void ShowData(); }; void main(){ clrscr(); cout << \"CARD DECK PROGRAM STAGE #5\" << endl; CardDeck D; D.ShowData(); } CardDeck::CardDeck() { 467
C++من البداية إلى البرمجة الكيانية ;cout << endl << endl ;cout << \"CONSTRUCTOR CALL\" << endl ;NumDecks = 1 ;NumPlayers = 1 ;CardsLeft = NumDecks * 52 ;CardsDealt = 1 ;)(getch } {)(void CardDeck::ShowData ;cout << endl << endl ;cout << \"SHOW DATA FUNCTION\" << endl ;cout << endl ;cout << \"NumDecks: \" << NumDecks << endl ;cout << \"NumPlayers: \" << NumPlayers << endl ;cout << \"CardsLeft: \" << CardsLeft << endl ;cout << \"CardsDealt: \" << CardsDealt << endl ;)(getch } • المرحلة السادسة فري هرذ المرحلرة سريتم اضرافة خاصرية اخررى مرن خرواص الصرنف الا وهري دالرة الهردم ( .)destructorوهرذ دالرة عضرو عامرة اخررى يرتم اسرتدعاءها اليرا .فري الوقت الذي يتم فيره خلرق الكيران فران هرذ الدالرة لرم يرتم اسرتدعااها ،ولكرن برالاحرى عندما يكون الكيان لم يعد مستخدما بعد .هنا وقت عندما يرتم هردم الكيران ,فري ذلرك الوقت فان دالة الهدم يتم استدعاءها .لماذا هرذ ضررورية؟ فكرر فري دالرة الهردم علرى انها وضيفة او دالة الاعتناء بالبيرت (التردبير المنزلري) .كيانرك الانيرق ربمرا يكرون لره 468
د .نضال خضير العبادي /جامعة الكوفة [email protected] . متطلبات ذاكرة خاصة او يستخدم مصادر حاسوب خاص اخر والذي يحتاج الرى ان يضعة ثانية في ترتيبة .ربما المثال الجيد ياتي من الرسوم ،دالة البناء من الممكن ان تستخدم لوضع مخرجات الحاسوب في طور الرسوم ودالة الهدم تعيد الحاسوب الرى طرور الرنص الاعتيرادي .بصرراحة ،لايوجرد الكثيرر مرن الرذي ممكرن ان تعملرة مرع الصرنف ) )CardDeckالرذي يتطلرب التنميرف بعرد ذلرك .الان ،دالرة الهردم ستصردر رساله فقرط تبرين ان الدالرة ترم اسرتدعاءها .دالرة الهردم مناسربة بشركل مثرالي ،فري هرذ المرحلة ،من المهم ان تدر بان الهدم موجود. الصيغة القواعدية للهدم مشابهة جدا الى البناء .حي ان اسم الصنف هرو اسرم دالة الهردم مرع اسرتخدام العلامرة (~) بدايرة المعررف .تقليرديا فران الهردم يوضرع اسرفل البناء مباشرة في المقطع العام للصنف .نفذ البرنامج مع دالة الهردم الجديردة المضرافة واحسب او حدد بالضربط ايرن دالرة الهردم تقروم بعملهرا .الرسرالة الخارجرة لدالرة الهردم سوف تعطيك المعلومات المطلوبة. لاحظ اضافة دالة الهدم ،ان الغرر مرن دالرة الهردم هرو لالغراء ابترداء (اسرناد بيانات ابتدائية) لكيانات CardDeckالتي سبق وان تم خلقها. // Stage #6 >#include <iostream.h >#include <conio.h class CardDeck { private: ;int NumDecks ;int NumPlayers ;int CardsLeft ;int CardsDealt public: 469
من البداية إلى البرمجة الكيانيةC++ CardDeck(); ~CardDeck(); void ShowData(); }; void main() { clrscr(); cout << \"CARD DECK PROGRAM STAGE #6\" << endl; CardDeck D; D.ShowData(); } CardDeck::CardDeck() { cout << endl << endl; cout << \"CONSTRUCTOR CALL\" << endl; NumDecks = 1; NumPlayers = 1; CardsLeft = NumDecks * 52; CardsDealt = 1; getch(); } CardDeck::~CardDeck() { cout << endl << endl; cout << \"DESTRUCTOR CALL\" << endl; 471
د .نضال خضير العبادي /جامعة الكوفة [email protected] . ;)(getch } )(void CardDeck::ShowData { ;cout << endl << endl ;cout << \"SHOW DATA FUNCTION\" << endl ;cout << endl ;cout << \"NumDecks: \" << NumDecks << endl ;cout << \"NumPlayers: \" << NumPlayers << endl ;cout << \"CardsLeft: \" << CardsLeft << endl ;cout << \"CardsDealt: \" << CardsDealt << endl ;)(getch } • المرحلة السابعة الدالة العضو ( )ShowDataتساعد على عر الصيغة القواعديرة الصرحيحة للدوال التي هي اعضاء في الصرنف .فري الحقيقرة هرو لريب مثرال جيرد لكيفيرة تعامرل الردوال الاعضراء مرع البيانرات الاعضراء .لنضرعها بكرلام اخرر ،انهرا لريب مثرال جيرد لكيفية وصول الافعال او الطرق ( )actionللصنف الى صفات ( )attributeالصنف. لذلك ماالذي بالضبط يقوم به اي واحد مع طاولة الورق؟ الاوراق خلطت ،اللاعبون يتعراطون الرورق ،يقطعرون ،ويسرتخدمونها بافعرال عديردة مختلفرة تكرون مطلوبرة مرن العاب الورق المختلفة .لغاية الان نحافظ عليها بسيطة .هذا الصنف الصغير سيعطي الفرصة لخلط الاوراق .التعامل مع الورق وتحديد عدد الورق الباقي. الرررردوال ( )ShuffleCards, and dealhandهرررري دوال ( )voidالدالررررة ) )CheckCardsLeftتعيرد عردد صرحيح .هرذ المرحلرة تضريف فقرط الشركل العرام او النمروذج فرري الصررنف ( .)CardDeckالبرنرامج التررالي شرركل عرام للرردوال الاعضرراء 471
من البداية إلى البرمجة الكيانيةC++ مرررع العلرررم ان البرنرررامج لرررمShuffleCards, DealHand and CheckCardsLeft .يعر باكملة // Stage #7 #include <iostream> #include <conio> class CardDeck { private: int NumDecks; int NumPlayers; int CardsLeft; int CardsDealt; public: CardDeck(); ~CardDeck(); void ShowData(); void ShuffleCards(); void DealHand(); int CheckCardsLeft(); }; void main() { clrscr(); cout << \"CARD DECK PROGRAM STAGE #7\" << endl; CardDeck D; 472
د .نضال خضير العبادي /جامعة الكوفة [email protected] . ;)(D.ShowData } • المرحلة الثامنة المرحلررة الثامنررة تنفررذ افعررال ) )actionsالصررنف الجديرردة المختررارة ،الرردوال، الدوال الاعضاء ،واي شيء .لايوجد جديرد نوضرحة .نبردأ الان ليكرون لردينا برنامجرا كرراملا .الكثيررر ربمررا يندهشررون بتنفيررذ الرردوال الاعضرراء .النمرررة الخاطفررة للدالررة ) )ShuffleCardsلاتعمرل اي شريء ،الرجراء افهرم هرذ النقطرة جيردا ،شرفرة البرنرامج التي تخلط رزمة من الورق لاتعمل اي شيء اطلاقا. ربما واجهت صعوبة بتعلم البرمجة الكيانية ابتداءا وذلك لانك وجدت شفرات برررررامج عديرررردة تبرررردو غيررررر مترابطررررة .مبرررردئيا نقررررول ان وظيفررررة او عمررررل دوال ) )ShuffleCardsهري لبيران ان الرورق يخلرط .الدالرة ) )CheckCardsLeftهري اكثرر اهمية فهي تصل الاعضاء الخاصين وتعالج المعلومرات .هرذ المرحلرة سرتلاحظ بهرا تنفيذ الدوال الاعضاء الجديدة DealHand, CheckCardsLeft , and ShuffleCards // Stage #8 >#include <iostream >#include <conio class CardDeck { private: ;int NumDecks ;int NumPlayers ;int CardsLeft ;int CardsDealt public: ;)(CardDeck 473
من البداية إلى البرمجة الكيانيةC++ ~CardDeck(); void ShowData(); void ShuffleCards(); void DealHand(); int CheckCardsLeft(); }; // continue هناك تِمَه // continue stage#8 تكمله void main() { clrscr(); cout << \"CARD DECK PROGRAM STAGE #8\" << endl; CardDeck D; D.ShowData(); D.ShuffleCards(); D.DealHand(); cout << \"There are \" << D.CheckCardsLeft() << \" cards left in the deck \" << endl; } CardDeck::CardDeck() { cout << endl << endl; cout << \"CONSTRUCTOR CALL\" << endl; NumDecks = 1; 474
[email protected] . جامعة الكوفة/ نضال خضير العبادي.د NumPlayers = 1; CardsLeft = NumDecks * 52; CardsDealt = 1; getch(); } CardDeck::~CardDeck() { cout << endl << endl; cout << \"DESTRUCTOR CALL\" << endl; getch(); } void CardDeck::ShowData() { cout << endl << endl; cout << \"SHOW DATA FUNCTION\" << endl; cout << endl; cout << \"NumDecks: \" << NumDecks << endl; cout << \"NumPlayers: \" << NumPlayers << endl; cout << \"CardsLeft: \" << CardsLeft << endl; cout << \"CardsDealt: \" << CardsDealt << endl; getch(); } void CardDeck::ShuffleCards() { cout << endl void CardDeck::DealHand() { 475
C++من البداية إلى البرمجة الكيانية ;cout << endl << endl ;cout << \"DEAL HAND FUNCTION\" << endl ;)(getch } )(int CardDeck::CheckCardsLeft { ;cout << endl << endl ;cout << \"CHECK CARDS LEFT FUNCTION\" << endl ;)(getch ;return CardsLeft } ;<< endl ;cout << \"SHUFFLE CARDS FUNCTION\" << endl ;)(getch } • المرحلة التاسعة هذ المرحلة تبين ان دوال البناء لها استعمالات اكثررمن ابترداء بيانرات صرنف عضو .فهي توضح ان الدالة العضو لها قابلية فريدة لاستدعاء دالة عضو اخرى في الصرنف .فري حالرة دالرة البنراء فهرذ لهرا فوائرد عمليرة .دوال البنراء المحسرنة فري هرذا البرنرررامج هررري لررريب فررري الحقيقرررة ذكيرررة ،ولكنهرررا تبرررين صرررفات مهمرررة .الصرررنف ) )CardDeckيحتروي الدالرة ) ،)ShuffleCardsوالخلرط هري صرفة عمليرة لاي لعبرة ورق ،وهرذ بالتاكيرد تنجرز مرن قبرل دالرة البنراء .ان وظيفرة دالرة البنراء هري لضربط المرحلرة المناسربة .وهري لاترتممن فقرط ابترداء المتغيررات بربعض القريم ،ولكرن ايضرا استدعاء الدالة المناسبة ،مثل ) ،)ShuffleCardsالمرحلة التاسعة تبين فقرط جرزء مرن البرنرامج الرذي يركرز علرى تغييررات بسريطة فري دالرة البنراء .فري برنرامج المرحلرة 476
[email protected] . جامعة الكوفة/ نضال خضير العبادي.د التاسعة فان هنا استخدام لدوال البناء المحسنة وايضا توضيح اسرتخدام دوال البنراء للتاكردShuffleCards ولكرن ايضرا اسرتدعاء دالرة،ليب لابتداء بيانات الاعضاء فقط .من خلط الاوراق لاي كيان جديد Stage #9 #include <iostream> #include <conio> class CardDeck { private: int NumDecks; int NumPlayers; int CardsLeft; int CardsDealt; public: CardDeck(); ~CardDeck(); void ShowData(); void ShuffleCards(); void DealHand(); int CheckCardsLeft(); }; void main() { clrscr(); cout << \"CARD DECK PROGRAM STAGE #9\" << endl; CardDeck D; 477
C++من البداية إلى البرمجة الكيانية ;)(D.ShowData ;)(D.ShuffleCards ;)(D.DealHand )(cout << \"There are \" << D.CheckCardsLeft ;<< \" cards left in the deck \" << endl } )(CardDeck::CardDeck { ;cout << endl << endl ;cout << \"CONSTRUCTOR CALL\" << endl ;NumDecks = 1 ;NumPlayers = 1 ;CardsLeft = NumDecks * 52 ;CardsDealt = 1 ;)(ShuffleCards ;)(getch } • المرحلة العاشرة دالة البناء التي رأيتها سابقا هي دالرة البنراء الافتراضرية .حترى مرع التحسرينات في البرنامج الاخير في المرحلة التاسعة ،فهو لازال مرن تخطيطرك .هرذ الدالرة تبتردأ الكيان الجديرد وفقرا الرى مواصرفات افتراضرية C++ .يعلرم ان دالرة البنراء الافتراضرية يجب ان تستدعى وذلك في حالة الكيان الذي ليب له وسائط .العبارة مث ;CardDeck D تخلرق كيانرا جديردا ) )Dوهرذا لريب لره وسرائط اطلاقرا.هرذا يتررجم علرى انرره استدعاء لدالة البناء الافتراضية C++ .يعلم اي مرن دوال البنراء هرو افتراضري وذلرك 478
د .نضال خضير العبادي /جامعة الكوفة [email protected] . مرن خرلال ترردقيق اسرم دالررة البنراء والتري تسررتخدم فري راس الدالررة حير لاتحترروي على وسائط. لقد سبق وان درست تطابق الردوال ) )overloading functionوالتري لهرا تنفيرذ مختلف. ان اضرافة دالرة بنراء ثانيرة ،يعنري انرك تعردد اشركال دالرة البنراء .وهرذ ليسرت مشركلة ،طالمرا تعطري C++اشرارة واضرحة لمقصرد .دالرة البنراء الثانيرة تحتراج الرى بعض الوسائط وذلك للمساعدة على تمييزها عن الدالة الاولى .لماذا تحتاج الرى دالرة بناء ثانية؟ ماذا عن الاشارة الى ،كم عدد الاشخاص الذين يلعبون في مثالنا هذا ،كرم عردد رزم الرورق الواجرب خلطهرا .هرذ مرادة عمليرة وسريكون جمريلا اذا تمكنرت مرن السيطرة عليها. البرنرررامج اللاحرررق يخلرررق كيرررانين الكيررران الاول D1يسرررتدعي دالرررة البنررراء الافتراضرية (لاحرظ هنرا لاتوجرد وسرائط فري اي مكران قررب )D1نفرب دالرة البنراء القديمة .الكيان الثراني هرو D2يرتممن وسريطين ) D2 )4 ،5حير ان الررقم 4يمررر الى المتغير الذي يمثل عدد رزم الورق ،والرقم 5يمرر الى المتغير الذي يمثل عردد اللاعبين .دالة البناء الثانية متطابقرة الشركل ) )overloadedتهردف الرى عرر العردد الابتدائي لرزم الورق والعدد الابتدائي للاعبين للمسراعدة برالتمييز برين الردالتين .هرذا يوضح تطبيقا جيدا اخر لتطابق اشكال الدوال .نفذ هذا البرنامج وافحص المخرجات سوف تلاحظ نتائج ممتعة مختلفة .في هذا البرنامج تمت اضافة دالة بناء ثانية والتي تبتدأ NumDecksوكذلك NumPlayersلتحديد قريمهم .اساسرا ،دالرة البنراء التري لريب لها وسائط ستستدعي دالة البناء الافتراضية. // Stage #10 >#include <iostream.h >#include <conio.h class CardDeck { 479
من البداية إلى البرمجة الكيانيةC++ private: int NumDecks; int NumPlayers; int CardsLeft; int CardsDealt; public: CardDeck(); CardDeck(int,int); ~CardDeck(); void ShowData(); void ShuffleCards(); void DealHand(); int CheckCardsLeft(); }; // continue هناك تِمَه لَبرنامج // continue with stage #10 تِمَة المرحَه الدا ر void main() { clrscr(); cout << \"CARD DECK PROGRAM STAGE #10\" << endl; CardDeck D1; D1.ShowData(); D1.ShuffleCards(); D1.DealHand(); 481
[email protected] . جامعة الكوفة/ نضال خضير العبادي.د cout << \"There are \" << D1.CheckCardsLeft() << \" cards left in the deck \" << endl; CardDeck D2(4,5); D2.ShowData(); D2.ShuffleCards(); D2.DealHand(); cout << \"There are \" << D2.CheckCardsLeft() << \" cards left in the deck \" << endl; } CardDeck::CardDeck() { cout << endl << endl; cout << \"CONSTRUCTOR CALL\" << endl; NumDecks = 1; NumPlayers = 1; CardsLeft = NumDecks * 52; CardsDealt = 1; ShuffleCards(); } CardDeck::CardDeck(int ND ، int NP) { cout << endl << endl; cout << \"SECOND CONSTRUCTOR CALL\" << endl; NumDecks = ND; NumPlayers = NP; cout << NumDecks << \" card decks will be shuffled for \" 481
من البداية إلى البرمجة الكيانيةC++ << NumPlayers << \" players\" << endl; CardsLeft = NumDecks * 52; CardsDealt = 1; ShuffleCards(); } CardDeck::~CardDeck() { cout << endl << endl; cout << \"DESTRUCTOR CALL\" << endl; getch(); } void CardDeck::ShowData() { cout << endl << endl; cout << \"SHOW DATA FUNCTION\" << endl; cout << endl; cout << \"NumDecks: \" << NumDecks << endl; cout << \"NumPlayers: \" << NumPlayers << endl; cout << \"CardsLeft: \" << CardsLeft << endl; cout << \"CardsDealt: \" << CardsDealt << endl; getch(); } // continue هناك تِمَه // continue with stage #10 تِمَة المرحَه الدا ر 482
[email protected] . جامعة الكوفة/ نضال خضير العبادي.د void CardDeck::ShuffleCards() { cout << endl << endl; cout << \"SHUFFLE CARDS FUNCTION\" << endl; getch(); } void CardDeck::DealHand() { cout << endl << endl; cout << \"DEAL HAND FUNCTION\" << endl; getch(); } int CardDeck::CheckCardsLeft() { cout << endl << endl; cout << \"CHECK CARDS LEFT FUNCTION\" << endl; getch(); return CardsLeft; } الدوال والاشكال المتعددة، المؤشرات9.28 Pointers ،Virtual Functions and Polymorphism • Polymorphism ،وتعنري الاشركال المتعرددة هري واحردة مرن اهرم الصرفات فري البرمجرة الكيانيرة سرربق وان رايررت كيفيررة تنفيررذ التطررابق (وهرري مشررابهة لتعرردد الاشرركال) باسررتخدام .)) (الدوال التي تختلف بالوسائط وتتشابه بالاسماءoverloaded( 483
C++من البداية إلى البرمجة الكيانية الردوال الاعضراء المتطابقرة يرتم اختيرار احرداها عنرد الاسرتدعاء وعنرد تطرابق الوسائط من حي العدد والنوع وهذ المعلومات تكون معروفرة للمتررجم اثنراء وقرت الترجمة .هرذ تسرمى سرابقا الرربط ( )bindingاو الرربط السراكن ( )static bindingاو ( )static linkingوتسرمى ايضرا ( .)compile time polymorphismسرابقا كران الرربط ( )bindingيعنري ببسراطة ان الكيران يرربط بالدالرة التري تسرتدعية فري وقرت الترجمرة. الان لنفتر وجود الحالة التالية التي يكون فيها اسم الدالة وشكلها هو نفسة في كرل من الصنف الاساس والمشتق ..مثال لنفتر تعريف الصنف التالي { Class A ; int x public : هذ الدالة هي في الصنف الاساس // } void show () { ………. ;} { class B : class A ; int y public : هذ الدالة هي في الصنف المشتق // } void show () { …….. ;} كيرررف يمكرررن ان تسرررتخدم الدالرررة العضرررو (() )showلطباعرررة القررريم لكيانرررات الاصرناف ( )A ، Bحير ان النمروذج ()( )showهرو ذاترة فري المروقعين وحير ان الدالة غير متطابقة لرذا لايمكرن ربطهرا فري وقرت الترجمرة .فري الحقيقرة فران المتررجم لايعرف مايعمرل والقررار مختلرف .مرن المناسرب اذا مرا اختيررت دالرة عضرو مناسربة عند تشغيل البرنامج ،هذ الحالة تسمى تعدد الاشكال في وقرت التنفيرذ .كيرف يحردث ذلك ؟ لغة C++تدعم الية تعرف او تسرمى (( )virtual functionالدالرة الافتراضرية) للوصول الى تعدد اشكال وقت التنفيذ .الشكل ( )9.4ادنا 484
د .نضال خضير العبادي /جامعة الكوفة [email protected] . تعدد الاشكال تعدد الاشكال وقت تعدد الاشكال وقت الترجمة التنفيذ تطابق الدوال تطابق الوسائط الدوال الافتراضية الشكل ( :)9.4يوضح تعدد الاشكال في وقت التنفيذ عندما يتم معرفة ماهي كيانات صنف معين فان نسخة مناسبة من الدالة سيتم استدعااها وحي ان الدالة تربط مع صنف معين بوقت مترأخر كثيرر عن وقت الترجمة فان هذ العملية ستسمى (( )late bindingالربط المتأخر) وتسرمى ايضرا (( )dynamic bindingالرربط الالري) بسربب ان أختيرار الدالرة المناسربة يرتم أليرا في وقت التنفيذ .الربط الالي واحردة مرن الصرفات القويرة فري لغرة C++وهرذ تتطلرب استخدام مؤشرات للكيانات. • مؤشرات الكيانات Pointers of Objects C++تسمح لك تعريف صنف يحتوي على انواع مختلفة من البيانات والدوال كاعضاء. C++تسرمح لرك كرذلك الوصرول الرى اعضراء الصرنف مرن خرلال المؤشررات ولغرر تحقيرق ذلرك فران C++تروفر لرك مجموعرة مرن ثلاثرة عوامرل تؤشرر الرى الاعضاء وهي جدول 9.2يوضح عوامل المرجعية والتاشير الوظيفــــــــــــــــــــــــــــــه العامل يعلن عن مؤشر الى عضو في صنف *:: للوصول الى عضو باستخدام اسم الكيان ومؤشر الى ذلك العضو * للوصول الى عضو باستخدام مؤشر الى كيان ومؤشر الى ذلك العضو >- 485
C++من البداية إلى البرمجة الكيانية لاحمت سابقا كيفية استخدام المؤشررات للوصرول الرى اعضراء الصرنف وكمرا عرفرت سرابقا فران المؤشرر بامكانرة ان يؤشرر الرى أي كيران يخلرق بواسرطة الصرنف. افر لديك العبارة التالية ; Item x حي ان ) )Itemهو صنف و ( )xهو كيان معرف من نوع الصنف (..)Item بنفب الطريقة من الممكن ان تعرف مؤشر ( )ptrمن نوع ( )Itemكمايأتي ; Item *ptr ان مؤشررات الكيران مفيردة عنرد خلرق الكيانرات وقرت التنفيرذ ومرن الممكرن ان تسرتخدم مؤشررر كيرران للوصررول الررى الاعضراء العامررة للكيرران .افررر ان الصررنف ( )Itemيعرف كما يأتي { class Item ; int code ; float price public I ) void getdata ( int a َfloat b } ; { code = a ; price = b ) void show ( void ; \" { cout << \" code : \" << code << \" \\n } ; \" cout << \" price : \" << price << \" \\n ;} الان لو اعلنت عن متغيرر ( )xمرن النروع ( )Itemومؤشرر ( )ptrالرى ( )xكمرا يأتي: ; Item x ; Item * ptr = &x 486
د .نضال خضير العبادي /جامعة الكوفة [email protected] . المؤشر ( )ptrسينشأ مع عنوان ( )xوبالامكان الاشرارة الرى الردوال الاعضراء للصررنف ) )Itemبطررريقتين ..واحرردة باسررتخدام عامررل النقطررة (الررربط مررع الكيرران بواسطة النقطة) والثانية باستخدام عامرل السرهم ومؤشرر الكيران لرذلك فران العبرارات التالية )x.getdata (1007 , 5.50 ; )(x.show مكافأة للعبارات التالية ; )Ptr -> getdata (100 7 , 5.50 ; )(Ptr -> show حي ان ( )*ptrهو متعلق مع ( )xممكن ايضا ان تستخدم الطريقة التالية ; )(( * ptr). Show في هذ الحالة نؤكد على اهمية الاقواس بسبب ان النقطة لها اسربقية عليرا مرن العامرل غيرر المباشرر (*) كرذلك بالامكران خلرق كيانرات باسرتخدام مؤشررات والعامرل ( )newكمايأتي: ; Item *ptr = new item هذ العبارة تخصص ذاكرة كافية للبيانات الاعضاء في هيكلية الكيران وتسرند عنروان الرذاكرة الرى ( )ptrبعرردها .ان ( )ptrممكرن ان يسرتخدم للاشرارة ل عضرراء كما يأتي ; )(Ptr -> show اما اذا استخدم الصنف (دالة بنراء) تسرتخدم وسرائط ولايحتروي علرى دالرة بنراء افتراضية (بدون وسائط) فانك يجب ان توفر الوسائط عند خلق الكيان ،كذلك يمكنك خلق مصفوفة من الكيانات باستخدام المؤشرات مثل ; ] Item *ptr = new item [ 10 مصفوفة من عشرة عناصر // 487
C++من البداية إلى البرمجة الكيانية فري التعبيرر اعرلا فانره سريتم خلرق مسراحة ذاكررة لمصرفوفة تتكرون مرن ()11 كيانات من النوع ) ،(Itemتذكر في بعض الحالات اذا ما احتوى الصنف على (دالرة بناء) فيجب ان يحتوي على (دالة بناء) بدون وسائط ايضا. • برنووامج لقووراءة عوودد موون العناووور مووع رمزهووا وسووعرها و بوواعته ،باسووتخدام الصنوف والمؤشرات // Example 9.19 >include<iostream { class item ; int code ; float price public : ) void getdata ( int a ،float b } ; { code = a ; price = b ) void show ( void ; \" { cout << n\" code : \" << code << \" \\n } ; \" cout << \" price : \" << price << \\n ;} ; const int size = 2 { )( main ; ] Item *p = new item [ size ; Item *d = p ; int x ، I ; float y ) for ( I = 0 ; I < size ; I++ ; { cout << \" input code and price for item \" << I+1 ; cin >> x >> y } ; p++ ; ) P -> getdata ( x ،y ) for ( I = 0 ; I > size ; I++ 488
د .نضال خضير العبادي /جامعة الكوفة [email protected] . ; \" { cout << \" item : \" << I+1 << \" \\n ; )(D ->show } ; D++ } 9.19عوامل ادارة ال اكرة Memory Management Operators لغرة Cتسرتخدم الردوال ()( )calloc() ،mallocلتخصريص الرذاكرة اليرا وقرت التنفيذ .وكذلك تستخدم الدالرة ( (freeلتحريرر الرذاكرة المخصصرة اليرا .تسرتخدم تقنيرة تخصيص الذاكرة الالي عندما لاتكون لك معرفة مسبقه بكمية او حجرم الرذاكرة التري تحتاجهرا .برالرغم مرن ان C++تردعم هرذ الردوال فهري ايضرا تعررف دالترين احاديرة العوامرررل (الوسرررائط) وهمرررا ( )delete ،newواللتررران تقومررران بتخصررريص وتحريرررر الرذاكرة بطريقرة سرهلة واكثرر مرونرة .ترذكر بران الكيران ممكرن ان يخلرق باسرتخدام ( )newويدمر باستخدام ( )deleteكلما احتجت الى ذلرك ،عليره فران حيراة الكيران هري تحت سيطرتك وهي لاتتعلق بالهيكل الكتلي للبرنامج ،كيان البيانرات المخلروق داخرل كتلرة مررع الامررر ( )newسرروف يبقررى بررالوجود حتررى يررتم ترردمير خارجيررا باسررتخدام (.)delete العامل ( )newيستخدم لخلق الكيانات من أي نوع ،والصيغة العامة له هي: ; Pointer-variable = new data-type هنا متغير المؤشر ( )pointer-variableهو مؤشر من (.( data-type ملاحظة//: العامرل ) (newيخصرص مسراحة ذاكررة كافيرة لحمرل بيانرات الكيران مرن نروعى ) (data-typeويعيرد عنروان الكيران (data-type) .ممكرن ان تكرون مرن أي نوع بيانات صحيحة. المتغير ( )pointer-variableيحمل عنوان مساحة الذاكرة التي ترم تخصيصرها مثال: 489
C++من البداية إلى البرمجة الكيانية ; P = new int ; Q = new float هنرا ( )Pمؤشرر مرن نروع الاعرداد الصرحيحة بينمرا ( )Qفهرو مؤشرر مرن نروع الاعداد الحقيقية ،تذكر ان ( )Q ،Pيجب ان يعلن عنهما ابتداءا كمؤشرات من انرواع مناسبة لمساحة الذاكرة المخصصة ; int *p = new int ; float * q = new float بالمقابل العبارات ; *p = 25 ; *q = 7.8 سروف تسرند القيمرة ( )25الرى الكيران مرن نروع الاعرداد الصرحيحة الرذي خلرق حديثا ,اما القيم ( )7.8فستسند الى كيان الاعداد الحقيقية .كذلك يمكن ان تنشا الذاكرة (باعطائها قيمة ابتدائية) باستخدام العامل ( )newوهذا يعمل كمايأتي: ; )Pointer-variable = new data-type (value هنا ( )valueتحدد القيمة الابتدائية مثال ; )int *p = new int (25 ; )float *q = new float (7.8 كما وضحنا سابقا فان ( )newممكن ان تستخدم لخلرق فضراء ذاكررة لاي نروع مررن البيانررات مررن ضررمنها الانررواع المعرفررة مررن قبررل المسررتخدم مثررل المصررفوفات، الهياكل ،والاصناف. الصيغة العامة لمصفوفة احادية هي ; ] Pointer-variable = new data-type [ size حي ان ( )sizeيمثل عدد عناصر المصفوفة .مثال لاحظ العبارة 491
د .نضال خضير العبادي /جامعة الكوفة [email protected] . ; ]int *p = new int [10 هرذ سرتخلق مسراحة ذاكررة لمصرفوفة متكونرة مرن عشررة عناصرر مرن نروع الاعداد الصحيحة ،وبالطبع فان (] )p[0سيشير الى العنصر الاول و (] )p[1سيشرير الى العنصر الثاني بالمصفوفة وهكذا.. من الممكن ان تخلرق مصرفوفة متعرددة المسرتويات مرع ( )newهنرا كرل حجروم المصفوفة يجب ان تجهز Array-ptr = new int [3][4][5] ; // اعلان صحيح Array-ptr = new int [m][5][4] ; // اعلان صحيح غير صحيح لوجود احد المستويات غير محدد Array-ptr = new int [3][4][] ; // الحجم Array-ptr = new int [][2][4] ; // غير صحيح البعد الاول ممكن ان يكون متغير له قيمة توفر في وقت سابق او وقت التنفيذ اما كل الابعاد الاخرى يجب ان تكون ثوابت. عنرردما لاتكررون هنررا حاجررة لبيانررات كيرران فرريمكن ترردميرها لتحريررر مسرراحة الرذاكرة التري تشرغلها واعرادة اسرتخدامها ..الصريغة العامرة لتردمير البيانرات وتحريرر الذاكرة المخصصة لها هي ; delete pointer-variable حي ان ( )pointer-variableهو مؤشر يشير الى بيانات كيان خلرق باسرتخدام ( )newمثال ; delete P ; delete Q اما اذا اردت تحريرر مصرفوفة خصصرت اليرا فانرك يجرب ان تسرتخدم الصريغة التالية 491
C++من البداية إلى البرمجة الكيانية ; delete [size] pointer-variable حير ان ( )sizeيحرردد عردد العناصررر بالمصررفوفة الواجرب تحريررر مسرراحتها المشركلة مرع هرذ الصريغة هرو ان المبررمج يجرب ان يترذكر حجرم المصرفوفة ،النسر الحديثة من C++لاتحتاج الى تحديد حجم المصفوفة كمايأتي ; delete [ ] p حي ستحرر كامل المصفوفة المؤشر عليها بواسطة (.(Q هنا يبرز سؤال ماذا يحصرل اذا لرم تتروفر ذاكررة كافيرة للتخصريص ؟ فري هرذ الحالة فران ( )newسريعيد مؤشررا فارغرا ( )nullعليره فران الفكرر الجيردة هري فحرص المؤشرات التي تنتجها ( )newقبل استخدامها ويتم ذلك كما يأتي: ; P = new int )If (!p } ; \" { cout << \" allocation failed \\n العامرررل ( )newلرررره محاسررررن عديررررد غيررررر موجررررودة فرررري (() )mallocمررررن هذ المحاسن: .1هري تحسرب اليرا حجرم بيانرات الكيران بحير لاتحتراج الرى اسرتخدام العامرل (.)sizeof .2تعيد نوع المؤشر الصحيح ،عليه فلا تحتاج الى استخدام النوع (.)cast .3من الممكن اعطاء قيم ابتدائية للكيان عند خلق مساحة الذاكرة. .4مثل أي عامل اخر فان ( )delete ،newممكن ان تتطابق. 9.31التأشير الى الاعضاء Pointers to Members من الممكن ان تأخذ عنوان الصنف العضو وتسند الى مؤشر عنوان العضو، وهذا من الممكن ان تحصل عليره عرادة باضرافة عامرل المرجعيرة (&) الرى التعريرف 492
د .نضال خضير العبادي /جامعة الكوفة [email protected] . الكامرل للدالرة وقبرل اسرم الصرنف ،امرا مؤشرر الصرنف العضرو ممكرن ان يعلرن عنره باستخدام العامل (* )::مع اسم الصنف فمثلا: { class A private: ; int m public: ; )(void show ;} الان بامكانك تعريف مؤشر الى العضو ( )mكما يأتي: ; int A::* ip = & A:: m المؤشرر ( )ipالمخلروق يعمرل مثرل الصرنف العضرو ( )class memberحير يجب ان يتم استدعاا مع كيان الصنف ،ففي العبارة أعرلا فرا (* )A::تعنري مؤشرر الرى عضرو مرن الصرنف ،امرا ( )& A:: mفهري تعنري عنروان العضرو ( )mالترابع للصنف (.)A لاحظ العبارة التالية فهي غير صحيحة ; int *ip = &m وذلرك بسربب كرون ( )mليسرت بيانرات مرن نروع الاعرداد الصرحيحة وهري لهرا معنى فقط عندما تشتر مع الصنف الذي تعود اليه ملاحظة//: علامة المدى ) ( ::يجب ان تطبق لكل من المؤشر والعضو المؤشر ( )ipممكن ان يسرتخدم الان للوصرول الرى العضرو ( )mداخرل الردوال الاعضاء (او الدوال الصديقة). افر ان ( )aهو كيان للصنف ( )Aمعلن عنه في الدالة العضو ،الان ممكن الوصول الى ( )mباستخدام المؤشر ( )ipكما يأتي: 493
C++من البداية إلى البرمجة الكيانية ; cout << a.*ip ; cout << a.m الان لاحظ العبارات التالية هنا ( ) Apمؤشر الى الكيان ) Ap = &a ; // (a هنا يتم عر cout << ap -> *ip ; // m cout << ap -> a ; // نفب الشيء اعلا عامرل اعرادة الاشرارة (*> )-يسرتخدم للوصرول الرى الاعضراء عنردما تسرتخدم مؤشررات الرى كرل مرن الكيران والعضرو أمرا عامرل اعرادة الاشرارة (* ).يسرتخدم عنرد استخدام الكيان نفسة مع مؤشر عضو .لاحظ ان ( )*ipيستخدم مثل اسم العضو .من الممكررن ايضررا تصررميم مؤشرررات للرردوال الاعضرراء والترري مررن الممكررن اسررتدعااها مستخدمين عوامل أعادة التأشير في الدالة الرئيسة (() )mainوكما يأتي: ; )( object-name. *pointer-to-member-function) (10 ; )( pointer-to-object -> * pointer-to-member-function) (10 الاسررربقية ل قرررواس والتررري هررري اعلرررى مرررن (* ).وكرررذلك (*> )-لرررذا فررران الاقواس ضرورية. • برنامج لايجاد مجموع عددين باستخدام المؤشرات والصنوف. // Example 9.20 >#include<iostream { class M ; int x ; int y public: ) void set-xy ( int a ، int b } ;{x=a ; y=b 494
د .نضال خضير العبادي /جامعة الكوفة [email protected] . ; ) friend int sum ( M m ;} ) int sum ( M m مؤ ر الى الدضو{ int M :: *px = &M :: x ; // x مؤ ر الى الدضو int M :: *py = &M :: y ; // y ; M *pm = &m مجموع ك من) int S = m.*px + pm -> *py ; // ( x+y } ; return S ; main () { M n ; void ( M :: *pf ) ( int ،int ) = &M :: set-xy مؤ ر الى الدالة ) // ( set-xy ; ) ( n.*pf ) ( 1011 ، ; \" cout << \" SUM = \" << sum ( n ) << \"\\n مؤ ر الى الِياإ M.*op = &n ; // n ; ) ( op -> *pf ) ( 3041 ، ; \" cout << \" SUM = \" << sum (n) << \" \\n ; ) return ( 0 } مطرجا البرنامج 9.20 SUM = 30 SUM = 70 9.31دالة الاستنساق Copy Constructor دالة الاستنساخ هي دالة بناء لها وسيط واحد يستدعى بالمرجعية وله نوع هرو نفب نروع الصرنف .ويجرب ان يكرون الوسريط هرو وسريط يسرتدعى بالمرجعيرة عرادة، 495
C++من البداية إلى البرمجة الكيانية الوسرريط هررو ايضررا وسرريط ثابررت ،بمعنررى يكررون مسرربوقا بررالمعرف ( .)constدالررة الاستنسرراخ للصررنف تسررتدعى اليررا طالمررا الدالررة تعيررد قرريم مررن نرروع الصررنف .دالررة الاستنساخ تستدعى اليا ايضا طالما هنا عامل يسد مسد وسيط يستدعى بالقيمة مرن نرروع هررذا الصررنف .دالررة الاستنسرراخ ممكررن ان تسررتخدم بررنفب طريقررة دوال البنرراء الاخرررى .اي صررنف يسررتخدم المؤشرررات والعامررل newيجررب ان يكررون لرره دالررة استنساخ. شكل 9.5يوضح اخفاء البيانات في الصنف 496
د .نضال خضير العبادي /جامعة الكوفة [email protected] . شكل 9.6تنظيم البيانات والدوال في البرمجة الكيانية 9.32عوامل التطابك Overloading Operators C++يدمج الاختيار لاسرتخدام العوامرل القياسرية لانجراز اعمرال مرع الصرنوف بالاضافة الى الاعمال مع الانواع الاساسية .كمثال ;int a ،b ،c ;a = b + c وهذا واضح على انه شرفرة مقبولرة فري ،C++حير ان الانرواع المختلفرة مرن المتغيرات في عملية الجمع هي جميعا من الانواع الاساسية ،ليب من الواضح جيردا بانه يمكنك ان تقوم باعمال مشابهة الى مايأتي: { struct ;string product ;float price 497
C++من البداية إلى البرمجة الكيانية ;} a ،b ،c ;a = b + c في الحقيقة ،هذ ستؤدي الى خطأ ترجمة ،وذلك لانك لم تعرف السلو الرذي يجرب ان يكرون عليره صرنفك مرع عمليرات الاضرافة .علرى كرل ،الشركر موصرول الرى صررفات C++بخصرروص تطررابق العوامررل ،فانرره يمكنررك ان تصررمم اصررناف قابلررة على انجاز عمليرات تسرتخدم عوامرل قياسرية .الجردول ادنرا يبرين كرل العوامرل القابلرة للتطابق: جدول :9.1يوضح العوامل القابلة للتطابق Overloadable operators << =+ - * / = < > += -= *= / >> ^ & <<= >>= == != <= >= ++ -- % |! )( ][ =->* -> ،~ &= ^= |= && || % new ][delete new[] delete ولغرر تطرابق عامرل مرا لغرر اسرتخدامة مرع الصرنوف فاننرا سرنعلن عرن دوال عامل ،والتي هي دوال اعتيادية اسمااها هي الكلمات المفتاحيرة للعامرل متبروع باشارة العامل الذي ترغب بتطابقة .الصيغة العامة هي: } type operator sign (parameters) { /*...*/ • برنامج لتطابق عامل الجمع ( .)+ستقوم بخلق صنف لخزن متجهات ثنائيرة الابعراد وبعردها سرتقوم بجمرع اثنرين مرنهم .)a(3,1) and b(1,2)( :ان جمرع اثنرين مرن المتجهررات ثنائيررة الابعرراد هرري عمليررة بسرريطة ببسرراطة جمررع اثنررين مررن احررداثيات x 498
[email protected] . جامعة الكوفة/ نضال خضير العبادي.د وكرذلك اضرافة قيمترين علرىx للحصول على نتيجة قيمة واحدة للاحداثي او المحور فري هرذ الحالرة.y للحصول على قيمة واحردة علرى الاحرداثيy المحور او الاحداثي .)3 ،+2) = (41 ،(3+1 ستكون النتيجة هي // Example 9.21 #include <iostream> using namespace std; class CVector { public: int x,y; CVector () { }; CVector (int, int); CVector operator + (CVector); }; CVector::CVector (int a ،int b) { x = a; y = b; } CVector CVector::operator+ (CVector param) { CVector temp; temp.x = x + param.x; temp.y = y + param.y; return (temp); } int main () { CVector a (3, 1); CVector b (1, 2); CVector c; c = a + b; 499
C++من البداية إلى البرمجة الكيانية ;cout << c.x << \",\" << c.y ;return 0 } مطرجا البرنامج 9.12 4, 3 ربمرا سريكون هنرا القليرل مرن التشرويش ان تررى عردد مرن المررات المعررف .CVectorلكررن ،اعتبرررر ان بعضرررها يشرررير الررى اسرررم الصرررنف (النررروع) CVector وبعضها الاخر هي دوال بهذا الاسم (دوال البنراء لهرا نفرب اسرم الصرنف) ،لاتشرتبهة بينهما CVector (int ، int); // اسم دالة البناء CVector ;)CVector operator+ (CVector الدالة ستعيد // CVector دالة العامل ( )+للصنف CVectorهي المسؤولة عرن تطرابق عامرل الاضرافة ( )+هذ الدالة من الممكن ان تستدعى اما داخليا باستخدام العامرل (عامرل الاضرافة) او خارجيا باستخدام اسم الدالة .لاحظ التعبيرين ;c = a + b ;)c = a.operator+ (b كلا التعبيرين متكافئين. لاحظ ايضا بان البرنامج 9.21احتوى ضمنا دالرة بنراء خاليرة (بردون وسرائط) وتم تعريفها بكتلة خالية ;} { )( CVector هذا ضروري ،حي لديك اعلان خارجي لدالة بناء اخرى: ;)CVector (int ، int 511
د .نضال خضير العبادي /جامعة الكوفة [email protected] . وعندما تعلن عن اي دالة بناء خارجية ،باي عدد من الوسائط ،فان دالة البناء الافتراضية بدون وسائط والتي يعلن عنهرا المتررجم اليرا سروف لاتعلرن ،لرذلك تحتراج الاعلان عنها بنفسك لغر ان تكون قادرا على بنراء كيانرات مرن ذلرك النروع بردون وسائط .في خلاف ذلك ،فان الاعلان: ;CVector c المضمن في الدالة الرئيسة ( )mainسوف لايكون مقبولا. في جميع الاحوال ،يجرب ان انبره الرى ان الكتلرة الخاليرة هري تنفيرذ سريء لدالرة البنراء ،وذلرك لانهرا لاتحقرق ادنرى وظيفرة تكرون متوقعرة بشركل عرام مرن دالرة البنراء، والتي هي ابتداء كل المتغيرات الاعضاء في الصنف .في حالتك هذ دالة البنراء هرذ ستتر المتغيرات ( )y ،xغير معرفين .لذلك ،فان التعريف الذي هو اكثر استحسانا يكون مشابهة لمايأتي: ;} ;CVector () { x=0; y=0 والتي ستبسط وتمهر فقط غاية الشفرة التي لم تممن في المثال. طالما ان الصرنف يحتروي دالرة البنراء الافتراضرية واستنسراخ دالرة البنراء حترى وان لم يكن معلن عنهرا ،فانهرا ايضرا تحتروي تعريرف افتراضري لعامرل المسراواة (=) مررع الصررنف نفسرره كوسرريط .السررلو الررذي يعرررف بررالافترا هررو استنسرراخ كررل المحتويات للبيانات الاعضاء للكيان الذي يمررر كوسريط (الرذي يكرون موجرود علرى يمين الاشارة الى ذلك الذي على الجانب الايسر): ;)CVector d (2, 3 ;CVector e ;e = d استنساخ عامل المساواة // ان دالرة استنسراخ عامرل الاسرناد او المسراواة هري دالرة العامرل العضرو الوحيرد الذي ينفذ برالافترا .برالطبع ،مرن الممكرن ان تعيرد تعريفرة الرى اي وظرائف اخررى اضرافية ترغرب بهرا ،كمثرال استنسراخ اعضراء صرنف محرددة فقرط ،او انجراز دوال 511
C++من البداية إلى البرمجة الكيانية ابتررداء اضررافية .تطررابق العوامررل لاتجبررر عملياتهررا الررى حمررل علاقررة الررى المعنررى الرياضي او معنى عام للعامل ،بالرغم من انها يوصى بها. مثرال ،الشرفرة ربمرا لاتكرون حدسرية اذا اسرتخدمت العامرل +لطررا صرنفين او استخدمت عامل الاسناد (=) لم صنف بالاصفار ،بالرغم مرن انره مرن المحتمرل جدا ان تعمل ذلك. بالرغم من ان شكل الدالة ( )operator +مرن الممكرن ان يررى بوضروا حير تاخذ ماموجود على الجانرب الايمرن للعامرل كوسريط لدالرة العامرل العضرو للكيران فري الجانب الايسر ،العوامل الاخرى لاتكون واضحة بدرجة كافية. جدول :9.3يوضح كيفية الاعلات عن الدوال الاعضاء المختلفة ( بدل الاشارة @ بالعامل في كل الحالات) Expression Operator Member function Global function @a + - * & ! ~ ++ -- )A::operator (@( operator@(A @a ++ -- )A::operator@(int) operator@(A,int a@b =! == > < | & ^ + - * / % )A::operator@ (B (operator@ (A,B <= >= << >> && || , a@b =& =^ == += -= *= /= % )A::operator@ (B - ][ =>> =<< =| - (a)b ،c... )( A::operator() (B ، )C... a->x >- )(>A::operator- - حي ان aهو كيران مرن الصرنف ،Aو bهرو كيران مرن الصرنف ،Bو cهرو كيان من الصنف .C من الممكن ان ترى في هذ المجموعة هنا طريقتران لتطرابق بعرض عوامرل الصنف :كدالة عضو وكدالة عامرة .اسرتخدامهما يختلرف ،لاتحتراج الرى ترذكير بران الدوال التي هري ليسرت اعضراء بالصرنف لايمكنهرا الوصرول الرى الاعضراء الخاصرة او المحميه لذلك الصنف مالم تكن هذ الدالة العامة صديقة . 512
د .نضال خضير العبادي /جامعة الكوفة [email protected] . 9.33الكلمة المفتاحية The Key Word This الكلمة المفتاحية thisتمثل مؤشرا الى كيران لره دالرة عضرو تحرت التنفيرذ .هري مؤشر الى الكيان نفسة. واحد مرن اسرتخداماتها هري مرن الممكرن ان تكرون لفحرص اذا مرا كران الوسريط الذي يمرر الدالة العضو هو الكيان نفسه. • برنامج لفح فيما اذا كان الوسيط ال ي يمرر الى الدالة هو الكيان نفسة. // Example 9.22 >#include <iostream ;using namespace std { class CDummy public: ;)int isitme (CDummy& param ;} )int CDummy::isitme (CDummy& param { ;if (¶m == this) return true ;else return false } { )( int main ;CDummy a ;CDummy* b = &a ) )if ( b->isitme(a ;\"cout << \"yes ،&a is b ;return 0 } 513
C++من البداية إلى البرمجة الكيانية مطرجا البرنامج 9.11 yes َ&a is b كررذلك هرري تسررتخدم باسررتمرار دالررة العامررل = العضررو والترري تعيررد الكيانررات بالمرجعية (تجنب استخدام الكيانات المؤقتة) .المتابعة مرع امثلرة المتجهرات مهرم قبرل ان يمكنك ان تكتب دالة العامل = مشابهة لما يأتي: )CVector& CVector::operator= (const CVector& param { ;x=param.x ;y=param.y ;return *this } فري الحقيقرة هرذ الدالرة مشرابهة جردا الرى الشرفرة التري يولردها المتررجم داخليرا الرى هرذا الصرنف اذا لرم تقرم بتممرين دالرة العامرل (=) العضرو لاستنسراخ الكيانرات لهذا الصنف. اسئلة للحل//: .1اكترب برنرامج لصرنف يمثرل الوقرت .كرل كيران فري هرذا الصرنف يمثرل وقت محدد من اليوم ,وخزن الساعة ,الدقيقة ,الثانية كاعداد صحيحة. يتضمن الصنف دالرة البنراء ,ودوال الوصرول مثرل دالرة تحديرد الوقرت الحرالي (سراعة ,دقيقرة ,ثانيرة) للكيران الموجرود ,اعرادة ضربط الوقرت ) (resetلكيان موجود ,ودالة الطباعة. .2اكتب برنامج لصنف عشوائي Randomلتوليد ارقام عشوائية. .3اكتب برنامج لتنفيذ صرنف لسلسرلة حرفيرة .Stringكرل كيران فري هرذا الصرنف يمثرل سلسرلة حرفيرة .البيانرات الاعضراء هري طرول السلسرلة, 514
Search
Read the Text Version
- 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
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 1 - 50
- 51 - 100
- 101 - 150
- 151 - 200
- 201 - 250
- 251 - 300
- 301 - 350
- 351 - 400
- 401 - 450
- 451 - 500
- 501 - 550
- 551 - 600
- 601 - 632
Pages: