آموزش ++C - بخش ششم
در قسمت های قبلی ، چند برنامه ساده ايجاد كرديم كه ميتوانستند پيغامهاي را به كاربر نشان داده، اطلاعاتي از وي دريافت نمايند، محاسباتي انجام داده و تصميمگيري كنند. در اين فصل، شروع به نوشتن برنامههايي ميكنيم كه مفاهيم پايه برنامهنويسي شيگراي معرفي شده در بخش 17-1 را بكار ميگيرند. يكي از ويژگيهاي مشترك در هر برنامه فصل دوم اين است كه تمام عبارات كه كاري انجام ميدهند در تابع جاي داده شدهاند. بطور كلي، برنامههايي كه در اين كتاب ايجاد ميكنيد، متشكل از تابع و يك يا چند كلاس كه هر يك حاوي اعضاي داده و توابع عضو هستند، خواهند بود. اگر شما عضوي از تيم توسعه (طراحي) در يك مجموعه حرفهاي هستيد، احتمال دارد بر روي سيستمهاي نرمافزاري كه حاوي صدها، يا هزاران كلاس است، كار كنيد. در اين فصل، هدف ما توسعه يك چهارچوب كاري ساده خوشفرم به لحاظ مهندسي نرمافزار به منظور سازماندهي برنامههاي شيگرا در C++ است.
ابتدا توجه خود را به سمت كلاسهاي موجود در دنياي واقعي متمركز ميكنيم. سپس به آرامي به سمت دنبالهاي از هفت برنامه كامل ميرويم كه به توصيف نحوه ايجاد و استفاده از كلاسهاي متعلق به خودمان ميپردازند. اين مثالها با مبحث آموزشي هدفمند كه بر توسعه كلاس grade-book تمركز دارد، شروع ميشود و مربي ميتواند از آن براي نگهداري امتيازات دانشجو استفاده كند. اين مبحث آموزشي در چند فصل آتي بهبود خواهد يافت و در فصل هفتم بحد اعلي خود خواهد رسيد.
اجازه دهيد بحث را با يك مقايسه ساده كه در افزايش درك شما از مطالب بخش 17-1 موثر است آغاز كنيم. فرض كنيد كه ميخواهيد با اتومبيلي رانندگي كرده و با فشردن پدال گاز آن را سريعتر به حركت در آوريد. چه اتفاقي قبل از اينكه بتوانيد اينكار را انجام دهيد، بايد رخ دهد؟ بسيار خوب، قبل از اينكه بتوانيد با اتومبيلي رانندگي كنيد، بايد كسي آن را طراحي و ساخته باشد. معمولاً ساخت اتومبيل، با ترسيم يا نقشهكشي مهندسي شروع شود. همانند طراحي صورت گرفته براي خانه. اين ترسيمات شامل طراحي پدال گاز است كه راننده با استفاده از آن سبب ميشود تا اتومبيل سريعتر حركت كند. تا حدي، پدال سبب «پنهان» شدن پيچيدگي مكانيزمي ميشود كه اتومبيل را سريعتر بحركت در ميآورد، همانطوري كه پدال ترمز سبب «پنهان» شدن مكانيزمي ميشود كه از سرعت اتومبيل كم ميكند، فرمان اتومبيل سبب «پنهان» شدن مكانيزمي ميشود كه اتومبيل را هدايت ميكند و موارد ديگر. با انجام چنين كارهايي، افراد عادي ميتوانند به آساني اتومبيل را هدايت كرده و براحتي از پدال گاز، ترمز و فرمان، مكانيزم تعويض دنده و ساير «واسطهاي» كاربرپسند و ساده استفاده كنند تا پيچيدگي مكانيزمهاي داخلي اتومبيل براي راننده مشخص نباشد.
متاسفانه، نميتوانيد با نقشههاي ترسيمي يك اتومبيل رانندگي كنيد، قبل از اينكه با اتومبيلي رانندگي كنيد بايد، آن اتومبيل از روي نقشههاي ترسيمي ساخته شود. يك اتومبيل كاملاً ساخته شده داراي پدال گاز واقعي براي به حركت درآوردن سريع اتومبيل است. اما اين هم كافي نيست، اتومبيل بخودي خود شتاب نميگيرد، از اينرو لازم است راننده بر روي پدال گاز فشار آورد تا به اتومبيل دستور حركت سريعتر را صادر كند.
حال اجازه دهيد تا از مثال اتومبيل مطرح شده براي معرفي مفاهيم كليدي برنامهنويسي شيگرا در اين بخش استفاده كنيم. انجام يك وظيفه در يك برنامه مستلزم يك تابع (همانند كه فصل دوم توضيح داده شده) است. تابع، توصيفكننده مكانيزمي است كه وظيفه واقعي خود را به انجام ميرساند. تابع پيچيدگي وظايفي كه قرار است انجام دهد از ديد كاربر خود پنهان ميسازد، همانند پدال گاز در اتومبيل كه پيچيدگي مكانيزم شتابگيري را از ديد راننده پنهان ميكند. در C++ ، كار را با ايجاد واحدي بنام كلاس كه خانه تابع محسوب ميشود، آغاز ميكنيم، همانند نقشه ترسيمي اتومبيل كه طرح پدال گاز نيز در آن قرار دارد. از بخش 17-1 بخاطر داريد كه به تابع متعلق به يك كلاس، تابع عضو گفته ميشود. در يك كلاس ميتوان يك يا چند تابع عضو داشت كه براي انجام وظايف كلاس طراحي شدهاند. براي مثال، يك كلاس ميتواند نشاندهنده يك حساب بانكي و حاوي يك تابع عضو براي ميزان سپرده در حساب، تابع ديگري براي ميزان برداشت پول از حساب و تابع سومي هم براي نمايش ميزان پول موجود در حساب باشد.
همانطوري كه نميتوانيد با نقشه ترسيمي اتومبيل رانندگي كنيد، نميتوانيد كلاسي را مشتق كنيد. همانطوري كه بايد قبل از اينكه بتوانيد با اتومبيلي رانندگي كنيد، شخص از روي نقشه ترسيمي مبادرت به ساخت اتومبيل كرده باشد، شما هم بايد قبل از اينكه برنامه بتواند وظايف توصيفي در كلاس را بدست آورد، بايد يك شي از كلاس را ايجاد كرده باشيد. اين يكي از دلايل شناخته شدن C++ بعنوان يك زبان برنامهنويسي شيگرا است. همچنين توجه نمائيد كه همانطوري كه ميتوان از روي نقشه ترسيمي اتومبيلهاي متعددي ساخت، ميتوان از روي يك كلاس، شييهاي متعددي ايجاد كرد.
زمانيكه رانندگي ميكنيد، با فشردن پدال گاز، پيغامي به اتومبيل ارسال ميشود كه وظيفهاي را انجام دهد، كه اين وظيفه افزودن سرعت اتومبيل است. به همين ترتيب، پيغامهايي را به يك شي ارسال ميكنيم، هر پيغام بعنوان فراخوان يك تابع عضو شناخته ميشود و به تابع عضو از شيي اعلان ميكند كه وظيفه خود را انجام دهد. اينكار غالباً بعنوان تقاضاي سرويس از يك شي شناخته ميشود.
تا بدينجا، از مقايسه اتومبيل براي توضيح كلاسها، شيها و توابع عضو استفاده كرديم. علاوه بر قابليتهاي اتومبيل، هر اتومبيلي داراي چندين صفت است، صفاتي همانند رنگ، تعداد درها، ظرفيت باك، سرعت جاري و مسافت طي شده. همانند قابليتهاي اتومبيل، اين صفات هم بعنوان بخشي از طراحي اتومبيل در نقشه ترسيمي ديده ميشوند. همانطوري كه رانندگي ميكنيد، اين صفات هميشه در ارتباط با اتومبيل هستند. هر اتومبيلي، حافظ صفات خود است. براي مثال، هر اتومبيلي از ميزان سوخت موجود در باك خود مطلع است، اما از ميزان سوخت موجود در باك ساير اتومبيلها مطلع نيست. به همين ترتيب، يك شي داراي صفاتي است كه به همراه شي بوده و در برنامه بكار گرفته ميشوند.
اين صفات به عنوان بخشي از كلاس شي تصريح ميشوند. براي مثال، يك شي حساب بانكي داراي صفت موجودي است كه نشاندهنده مقدار پول موجود در حساب ميباشد. هر شي حساب بانكي از ميزان موجودي در حساب خود مطلع است، اما از موجودي ساير حسابها در بانك اطلاعي ندارد. صفات توسط اعضاي داده كلاس مشخص ميشوند.
در مابقي اين فصل مبادرت به معرفي هفت مثال ساده ميكنيم كه به توصيف مفاهيم معرفي شده در ارتباط با قياس اتومبيل ميپردازند. خلاصهاي از اين مثالها در زير آورده شده است. ابتدا مبادرت به ايجاد كلاس ميكنيم تا قادر به توصيف اين مفاهيم باشيم:
1- اولين مثال نشاندهنده كلاس با يك تابع عضو است كه فقط يك پيغام خوشآمدگويي را در زمان فراخواني به نمايش در ميآورد. سپس شما را با نحوه ايجاد يك شي از اين كلاس و فراخواني تابع عضو كه پيغام خوشآمدگويي را ظاهر ميسازد، آشنا خواهيم كرد.
2- دومين مثال، اصلاح شده مثال اول است. در اين مثال به تابع عضو اجازه داده ميشود تا نام دوره را به عنوان يك آرگومان قبول كند. سپس، تابع عضو مبادرت به نمايش نام دوره بعنوان بخشي از پيغام خوشآمدگويي ميكند.
3- سومين مثال نحوه ذخيرهسازي نام دوره در يك شي را نشان ميدهد. براي اين نسخه از كلاس، شما را با نحوه استفاده از توابع عضو به منظور تنظيم نام دوره در شي و بدست آوردن نام دوره از شي آشنا ميكنيم.
4- چهارمين مثال به توصيف نحوه مقداردهي اوليه داده در شي به هنگام ايجاد شي ميپردازد. مقداردهي اوليه توسط يك تابع عضو بنام سازنده كلاس صورت ميگيرد. همچنين اين مثال نشان ميدهد كه هر شي از نام دورة خود نگهداري ميكند.
5- مثال پنجم اصلاح شده مثال چهارم است كه به توصيف نحوه قرار دادن كلاس در يك فايل مجزا به منظوراستفاده مجدد از نرمافزار، ميپردازد.
6- مثال ششم، تغييريافته مثال پنجم است كه حاوي يك اصل مهندسي نرمافزار در جداسازي بخش واسط كلاس از بخش پيادهسازي آن است. با انجام اينكار فرآيند اصلاح و تغيير آسانتر ميشود بدون اينكه در سرويسگيرندههاي كلاس تاثيرگذار باشد.
7- آخرين مثال قابليت كلاس را با معرفي اعتبارسنجي داده افزايش خواهد داد. اعتبارسنجي ما را از فرمت صحيح داده در يك شي مطمئن ميسازد. براي مثال يك شي نيازمند يك مقدار در محدودة 1 الي 12 است. در اين مثال ، تابع عضوي كه مبادرت به تنظيم نام دورة براي يك شي ميكند، سبب ميشود تا نام دوره 25 كاراكتر يا كمتر باشد. اگر طول نام دوره بيش از 25 كاراكتر باشد، تابع عضو فقط از 25 كاراكتر اول استفاده كرده و يك پيغام خطا به نمايش در ميآورد.
توجه كنيد كه مثالهاي در اين فصل فرآيند واقعي ذخيرهسازي را انجام نميدهند. در فصل چهارم، فرآيند پردازش امتيازات را با و در فصل هفتم مبادرت به ذخيرهسازي اطلاعات در يك شي خواهيم كرد.
كار را با مثالي آغاز ميكنيم (شكل 1-3) كه حاوي كلاس است و ميتوان از آن براي نگهداري امتيازات دانشجويان استفاده كرد. تابع در خطوط 20-25 مبادرت به ايجاد يك شي كرده است. اين برنامه نسخه اول بوده و نسخه كامل آن در فصل هفتم ايجاد خواهد شد. تابع از اين شي و تابع عضو آن براي نمايش پيغام بر روي صفحه نمايش (پيغام خوشآمدگويي) استفاده ميكند.
|
|
ابتدا به توصيف نحوه تعريف يك كلاس و تابع عضو ميپردازيم. سپس به توضيح نحوه ايجاد يك شي و نحوه فراخواني تابع عضو يك شي ميپردازيم. چند مثال اول حاوي تابع و كلاس است كه از آن در همان فايل استفاده ميكند. در انتهاي اين فصل، به معرفي روشهاي خبره در ساختارمند كردن برنامهها به منظور افزايش كارايي و انجام بهتر مهندسي نرمافزار خواهيم پرداخت.
قبل ا ز اينكه تابع (خطوط 20-25 ) بتواند شي از كلاس ايجاد كند، بايستي به كامپايلر توابع عضو و اعضاي داده متعلق به كلاس را اعلان كنيم. اين كار بنام تعريف كلاس شناخته ميشود. تعريف كلاس (خطوط 9-17 ) حاوي تابع عضوي بنام است (خطوط 13-16 ) كه پيغامي بر روي صفحه نمايش چاپ ميكند (خط 15 ). بخاطر داريد كه يك كلاس همانند يك نقشه ترسيمي است، از اينرو نياز داريم كه يك شي از كلاس ايجاد كنيم (خط 22 )، و تابع عضو آن را فراخواني نمايم (خط 23 ) تا خط 15 را به اجرا درآورده و پيغام خوشآمدگويي را به نمايش درآورد. بزودي به توضيح دقيقتر خطوط 22-23 خواهيم پرداخت.
تعريف كلاس از خط 9 و با كلمه كليدي و بدنبال آن نام كلاس آغاز شده است. بطور قراردادي، نام كلاسهاي تعريف شده توسط كاربر با حروف بزرگ شروع ميشوند و در صورت وجود كلمات بعدي، ابتداي آنها هم با حروف بزرگ آغاز ميگردد. به اين روش غالباً روش camel case ميگويند.
بدنه هر كلاسي در بين جفت براكت باز و بسته ( و ) محدود ميشود، همانند خطوط 10 و 17 . تعريف كلاس با يك سيمكولن خاتمه ميپذيرد (خط 17 ).
فراموش كردن سيمكولن در انتهاي تعريف يك كلاس، خطاي نحوي بدنبال خواهد داشت.
بخاطر داريد كه تابع هميشه و بصورت اتوماتيك به هنگام اجراي برنامه فراخواني ميشود. اكثر توابع بصورت اتوماتيك فراخواني نميشوند. همانطوري كه مشاهده خواهيد كرد، بايستي تابع عضو را بطور صريح فراخواني كنيد تا وظيفه خود را انجام دهد.
خط 14 حاوي برچسب تصريحكننده دسترسي است. كلمه كليدي ، تصريحكننده دسترسي ناميده ميشود. خطوط 13-16 تعريفكننده تابع عضو هستند. اين تابع عضو پس از قرار دارد تا نشان دهد كه تابع «بصورت سراسري در دسترس است»، به اين معني كه ميتواند توسط ساير توابع موجود در برنامه و توسط توابع عضو كلاسهاي ديگر فراخواني گردد. هميشه در مقابل تصريحكنندههاي دسترسي يك كولن ( ) قرار داده ميشود. براي مابقي متن، زمانيكه به تصريحكننده دسترسي اشاره ميكنيم، كولن آن را در نظر نميگيريم. در بخش 6-3 به معرفي دومين تصريحكننده دسترسي بنام خواهيم پرداخت.
هر تابعي در برنامه وظيفهاي را انجام داده و امكان دارد مقداري را پس از كامل كردن وظيفه خود برگشت دهد. براي مثال، تابعي ميتواند يك محاسبه انجام داده و سپس نتيجه آن محاسبه را برگشت دهد. زمانيكه تابعي تعريف ميشود، بايد نوع برگشتي آن را مشخص سازيد، تا تابع پس از اتمام كار، آن نوع را برگشت دهد. در خط 13 ، كلمه كليدي قرار گرفته است (در سمت چپ نام تابع ) و نشاندهندة نوع برگشتي از سوي تابع است. نوع برگشتي بر اين نكته دلالت دارد كه وظيفهاي را انجام خواهد داد، اما دادهاي را به فراخوان خود (در اين مثال، تابع فراخوان، ميباشد) پس از اتمام وظيفه خود برگشت نخواهد داد. (در شكل 5-3 مثالي را مشاهده ميكنيد كه تابع در آن مقداري را برگشت داده است).
نام تابع عضو بوده و قبل از آن نوع برگشتي قرار دارد. بطور قراردادي، اسامي توابع با يك حرف كوچك شروع شده و تمام كلمات متعاقب آن با حرف بزرگ شروع ميشوند. پرانتزهاي قرار گرفته پس از نام تابع عضو، بر اين نكته دلالت دارند كه اين يك تابع است. يك جفت پرانتز خالي، همانند خط 13 ، نشان ميدهد كه اين تابع عضو، نيازي به داده اضافي براي انجام وظيفه خود ندارد. در بخش 5-3 شاهد تابع عضوي خواهيد بود كه براي انجام وظيفه خود نيازمند داده اضافي است. معمولاً به خط 13 ، سرآيند تابع گفته ميشود. بدنه هر تابعي با براكتهاي باز و بسته مشخص ميشود ( و )، همانند خطوط 14 و 16 .
بدنه تابع حاوي عباراتي است كه وظيفه تابع را به انجام ميرسانند. در اين مورد، تابع عضو displayMessage حاوي يك عبارت است (خط 15 ) كه پيغام "Welcome to the Grade Book!" را به نمايش در ميآورد. پس از اجراي اين عبارت، تابع وظيفه خود را به انجام رسانده است.
برگشت دادن مقداري از يك تابع كه نوع برگشتي آن بصورت اعلان شده است، خطاي كامپايلر بدنبال خواهد داشت.
تعريف تابعي در درون تابع ديگر، خطاي نحوي است.
در اين مرحله ميخواهيم كه از كلاس در برنامه استفاده كنيم. همانطوري كه در فصل دوم آموختيد، تابع با اجراي هر برنامهاي شروع بكار ميكند. خطوط 20-25 از برنامه شكل 1-3 حاوي تابع هستند، كه اجراي برنامه را تحت كنترل دارد.
در اين برنامه، مايل هستيم تابع عضو از كلاس براي نمايش پيغام خوشآمدگويي اجرا گردد (فراخواني شود). اصولاً تا زمانيكه شيي از يك كلاس ايجاد نكرده باشيد، نميتوانيد تابع عضو كلاس را فراخواني نمائيد (در بخش 7-10 با تابع عضو ، آشنا خواهيد شد كه در اين مورد يك استثناء ميباشد.) خط 22 يك شي از كلاس بنام ايجاد ميكند. دقت كنيد كه نوع متغير است، كلاس تعريف شده در خطوط 9-17 . زمانيكه متغيرهايي از نوع اعلان ميكنيم، همانند كاري كه در فصل دوم انجام داديم، كامپايلر از مفهوم مطلع است و ميداند كه آن يك نوع بنيادين ميباشد. با اين وجود، زمانيكه مبادرت به نوشتن خط 22 ميكنيم، كامپايلر بصورت اتوماتيك از مفهوم نوع اطلاعي ندارد و آن را نميشناسد، اين نوع يك نوع تعريف شده توسط كاربر است. از اينرو، بايد به كامپايلر، با قرار دادن تعريف كلاس همانند كاري كه در خطوط 9-17 انجام دادهايم، را معرفي كنيم. اگر اين خطوط را حذف كنيم، كامپايلر پيغام خطايي همانند " 'GradeBook' : undeclared identifier" را در GNU C++ صادر ميكند. هر كلاس جديدي كه ايجاد ميكنيد، تبديل به يك نوع جديد ميشود كه ميتواند براي ايجاد شيها بكار گرفته شود. برنامهنويسان ميتوانند در صورت نياز مبادرت به تعريف كلاسهاي با نوع جديد نمايند، و اين يكي از دلايل شناخته شدن C++ بعنوان يك زبان بسطپذير است.
خط 23 مبادرت به فراخواني تابع عضو (تعريف شده در خطوط 13-16 ) با استفاده از متغير و بدنبال آن عملگر نقطه ( )، سپس نام تابع و يك جفت پرانتز خالي ميكند. اين فراخواني موجب ميشود كه تابع براي انجام وظيفه خود فراخواني شود. در ابتداي خط 23 ، عبارت "" بر اين نكته دلالت دارد كه بايستي از شي كه در خط 22 ايجاد شده است، استفاده نمايد. پرانتزهاي خالي در خط 13 نشان ميدهند كه تابع عضو نيازي به داده اضافي براي انجام وظيفه خود ندارد. (در بخش 5-3، با نحوه ارسال داده به تابع آشنا خواهيد شد) زمانيكه وظيفه خود را انجام داد، تابع به اجراي خود از خط 24 ادامه خواهد داد، كه نشان ميدهد وظيفه خود را به بدرستي انجام داده است. با رسيدن به انتهاي ، برنامه خاتمه ميپذيرد.
از بخش 17-1 بخاطر داريد كه UML يك زبان گرافيكي بكار رفته توسط برنامهنويس براي نمايش سيستمهاي شيگرا به يك روش استاندارد است. در UML ، هر كلاس در يك دياگرام كلاس و بصورت يك مستطيل با سه قسمت (بخش) مدلسازي ميشود. شكل 2-3 نشاندهنده يك دياگرام كلاس UML براي كلاس معرفي شده در برنامه 1-3 است. بخش فوقاني حاوي نام كلاس است، كه در وسط قرار گرفته و بصورت توپر نوشته ميشود. بخش مياني، حاوي صفات كلاس است كه مرتبط با اعضاي داده در C++ است. در شكل 2-3 بخش مياني خالي است، چرا كه اين نسخه از كلاس در برنامه 1-3 داراي صفات نيست. (در بخش 6-3 نسخهاي از كلاس عرضه شده كه داراي يك صفت است.) بخش تحتاني حاوي عمليات كلاس است، كه متناظر با توابع عضو در C++ ميباشد.
UML مبادرت به مدلسازي عملياتها با ليست كردن نام عمليات و بدنبال آن مجموعه پرانتزها ميكند. كلاس فقط داراي يك تابع عضو بنام است، از اينرو بخش تحتاني در شكل 2-3 فقط يك عمليات با اين نام را ليست كرده است. تابع عضو براي انجام وظيفه خود نيازي به اطلاعات اضافي ندارد، از اينرو پرانتزهاي قرار گرفته پس از در اين دياگرام كلاس خالي هستند، همانند سرآيند تابع عضو قرار گرفته در خط 13 برنامه1-3. علامت جمع ( ) كه قبل ا ز نام عمليات آورده شده، نشان ميدهد كه يك عمليات سراسري در UML است (يك تابع عضو در C++ ). به دفعات از دياگرامهاي كلاس UML براي خلاصه كردن صفات و عمليات كلاسها استفاده خواهيم كرد.
در مثال قياس اتومبيل در بخش 2-3 خاطرنشان كرديم كه فشردن پدال گاز سبب ارسال پيغامي به اتومبيل ميشود تا وظيفهاي را به انجام برساند، كه در اين مورد افزودن سرعت اتومبيل است. اما اتومبيل بايد چقدر سرعت بگيرد؟ همانطوري كه ميدانيد، با فشردن هر چه بيشتر پدال، سرعت اتومبيل افزايش پيدا ميكند. بنابر اين پيغام ارسالي به اتومبيل هم حاوي وظيفه بوده و همچنين حاوي اطلاعات ديگري است كه به اتومبيل در انجام وظيفه كمك ميكند. اين اطلاعات اضافي بنام پارامتر شناخته ميشوند، مقدار پارامتر به اتومبيل كمك ميكند تا ميزان افزايش سرعت را تعيين كند. به همين ترتيب، يك تابع عضو ميتواند نيازمند يك يا چندين پارامتر بعنوان داده اضافي براي انجام وظيفه خود باشد. فراخوان تابع مقاديري بنام آرگومان، براي هر پارامتر تابع تدارك ميبيند. براي مثال، در سپردهگذاري در حساب بانكي، فرض كنيد تابع عضو از كلاس پارامتري كه نشاندهنده مقدار سپرده است، مشخص كرده باشد. زمانيكه تابع عضو فراخواني شود، مقدار آرگومان كه نشاندهنده مقدار سپرده است به پارامتر تابع عضو كپي ميشود. سپس تابع عضو اين مقدار سپرده را به ميزان موجودي اضافه ميكند.
مثال بع دي (برنامه شكل 3-3) تعريف مجددي از كلاس (خطوط 14-23 ) با تابع عضو است (خطوط 18-22 ) كه نام دوره را بعنوان بخشي از رشته خوشآمدگويي چاپ ميكند. تابع عضو جديد مستلزم يك پارامتر است ( در خط 18 ) كه نشاندهنده نام دوره است.
قبل از اينكه به بررسي ويژگيهاي جديد كلاس بپردازيم، اجازه دهيد به نحوه استفاده از كلاس جديد در نگاهي داشته باشيم (خ طوط 26-40 ). در خط 28 يك متغير از نوع رشته () بنام ايجاد شده است كه از آن براي ذخيره كردن نام دوره وارد شده توسط كاربر استفاده خواهيم كرد. متغير از نوع نشاندهنده رشتهاي از كاراكترها همانند "CS101 Introduction to C++ Programming" است. نوع در واقع شي از كلاس كتابخانه استاندارد C++ است. اين كلاس در فايل سرآيند تعريف شده و نام همانند ، متعلق به فضاينامي است. براي اينكه خط 28 قادر به كامپايل شدن باشد، خط 9 حاوي سرآيند است. دقت كنيد كه اعلان در خط 10 به ما اجازه ميدهد تا به آساني در خط 28 از بجاي استفاده كنيم. براي اين لحظه، ميتوانيد در مورد متغيرهاي همانند متغيرهاي از نوع ديگر همانند فكر كنيد. در بخش 10-3 با قابليتهاي بيشتر آشنا خواهيد شد.
خط 29 يك شي از كلاس بنام ايجاد ميكند. خط 32 به كاربر اعلان ميكند كه نام دوره را وارد سازد. خط 33 مبادرت به خواندن نام دوره از ورودي كاربر كرده و آن را با استفاده از تابع كتابخانهاي به متغير تخصيص ميدهد. قبل از اينكه به توضيح اين خط از كد بپردازيم، اجازه دهيد تا توضيح دهيم چرا نميتوانيم براي بدست آوردن نام دوره فقط بنويسيم
در اجراي نمونه اين برنامه، ما از نام دوره "CS101 Introduction to C++ Programming" استفاده كردهايم كه حاوي چندين كلمه است. زمانيكه با عملگر استخراج به كار گرفته ميشود، مبادرت به خواندن كاراكترها تا رسيدن به اولين كاراكتر white-space ميكند. از اينرو فقط "CS101" توسط اين عبارت خوانده ميشود و براي خواندن مابقي نام دوره مجبور به عمليات ورودي اضافي خواهيم بود.
در اين مثال، مايل هستيم تا كاربر نام كامل دوره را تايپ كرده و كليد Enter را براي تحويل آن به برنامه فشار دهد، و كل نام دوره در متغير رشتهاي ذخيره گردد فراخواني تابع cin, nameOfCourse در خط 33 ، سبب ميشود كه كاراكترها (از جمله كاراكترهاي فاصله كه كلمات را از هم در ورودي جدا ميكنند) از شي ورودي استاندارد جريان (صفحه كليد) تا رسيدن به كاراكتر خط جديد خوانده شده و در متغير رشتهاي جاي داده شده و كاراكتر خط جديد حذف ميگردد. توجه نمائيد زمانيكه كليد Enter فشرده ميشود (در زمان تايپ ورودي)، يك خط جديد (newline) به جريان ورودي افزوده ميشود. همچنين توجه كنيد كه فايل سرآيند بايد قرار داشته باشد تا بتوان از تابع استفاده كرد. نام اين تابع متعلق به فضاي نامي است.
|
Please enter the course name:
Welcome to the grade book for CS101 Introduction to C++ Programming! |
خط 38 تابع عضو شي را فراخواني ميكند. موجود در درون پرانتزها آرگوماني است كه به تابع ارسال ميشود، از اينروست كه تابع ميتواند وظيفه خود را به انجام رساند. مقدار متغير در تبديل به مقدار پارامتر تابع عضو در خط 18 ميشود. زمانيكه اين برنامه اجرا شود، توجه نمائيد كه تابع عضو به همراه پيغام خوشآمدگويي، نام دورة تايپ شده توسط كاربر را به نمايش درميآورد.
براي تصريح اينكه تابعي ني ازمند داده براي انجام وظايف خويش است، اطلاعات اضافي را در ليست پارامتري تابع قرار ميدهيم، ليستي كه در درون پرانتزها قرار گرفته پس از نام تابع جاي دارد. ليست پارامترها ميتواند به هر تعداد پارامتر داشته باشد يا اصلاً پارامتري نداشته باشد (همانند پرانتزهاي خالي در خط 13 برنامه شكل 1-3) تا نشان دهد تابع نياز به هيچ پارامتري ندارد. ليست پارامتري تابع عضو به نحوي اعلان شده كه تابع نيازمند يك پارامتر است (شكل 3-3، خط 18 ). هر پارامتر بايد داراي نوع و يك شناسه باشد. در اين مورد، نوع بوده و شناسه است و نشان ميدهد كه تابع عضو مستلزم يك رشته براي انجام وظيفه خويش است. بدنه تابع عضو از پارامتر براي دسترسي به مقدار ارسالي به تابع در فراخواني تابع (خط 38 در ) استفاده ميكند. خطوط 20-21 مقدار پارامتر را بعنوان بخشي از پيغام خوشآمدگويي به نمايش در ميآورد. توجه نمائيد كه نام متغير پارامتري (خط 18 ) ميتواند همنام متغير آرگومان (خط 38 ) يا نام متفاوتي داشته باشد. در فصل ششم با دلايل اينكارها آشنا خواهيد شد.
يك تابع ميتواند داراي چندين پارامتر باشد، بشرطي كه هر پارامتر از ديگري با يك ويرگول مجزا شده باشد (در مثال شكلهاي 4-6 و 5-6 شاهد آنها خواهيد بود). تعداد و ترتيب آرگومانها در يك تابع فراخواني شده بايستي با تعداد و ترتيب ليست پارامترها در سرآيند تابع عضو فراخواني شده مطابقت داشته باشد. همچنين، نوع آرگومانها در تابع فراخواني شده بايد با نوع پارامترهاي متناظر در سرآيند تابع مطابقت داشته باشد. (همانطوري كه جلوتر ميرويم، شاهد خواهيد بود كه نوع يك آرگومان ميتواند همانند نوع پارامتر متناظر خود نباشد.) در مثال ما، يك آرگومان رشتهاي در تابع فراخواني شده وجود دارد () كه دقيقاً با پارامتري رشتهاي در تعريف تابع عضو مطابقت دارد () .
قراردادن يك سيمكولن پس از پرانتز سمت راست در ليست پارامتري تعريف تابع، خطاي نحوي است.
تعريف يك پارامتر تابع همانند يك متغير محلي در تابع، خطاي كامپايل بدنبال خواهد داشت.
از ابهام اجتناب كنيد، از اسامي يكسان براي آرگومانهاي ارسالي به تابع و پارامترهاي متناظر در تعريف تابع، استفاده نكنيد.
براي توابع و پارامترها اسامي با معني انتخاب كنيد تا خوانايي برنامه افزايش يافته و نياز به افزودن توضيحات را كم نمايد.
دياگرام كلاس UML در شكل 4-3 مبادرت به مدلسازي كلاس از برنامه 3-3 كرده است. همانند كلاس تعريف شده در برنامه 1-3، اين كلاس حاوي يك تابع عضو سراسري است. با اين وجود، اين نسخه از داراي يك پارامتر ميباشد. UML پارامتر را با ليست كردن نام پارامتر، بدنبال آن يك كولن و سپس نوع پارامتر در درون پرانتزهاي قرار گرفته پس از نام عمليات مدلسازي ميكند. UML داراي نوع دادههاي متعلق بخود شبيه C++ است. UML يك زبان مستقل بوده و از آن در كنار انواع زبانهاي برنامهنويسي استفاده ميشود، از اينرو اصطلاحات تخصصي آن دقيقاً مطابق با C++ نيست. براي مثال، نوع رشته () در UML متناظر با نوع در C++ است. تابع عضو از كلاس (شكل 3-3 خطوط 18-22 ) داراي يك پارامتر رشتهاي بنام است، از اينرو در شكل 4-3 بصورت در ميان پرانتزها و پس از نام ، قرار گرفته است. دقت كنيد كه اين نسخه از كلاس هنوز داراي اعضاي داده نيست.
در فصل دوم، تمام متغيرهاي برنامه را در تابع اعلان كرديم. متغيرهاي اعلان شده در بدنه تعريف يك تابع، بنام متغيرهاي محلي شناخته ميشوند و ميتوانند فقط از خطي كه در آن تابع اعلان شدهاند تا رسيدن به براكت بستن سمت راست ( ) در تعريف تابع بكار گرفته شوند. قبل از اينكه بتوان از يك متغير محلي استفاده كرد، بايد ابتدا آن را اعلان كرده باشيد. زمانيكه تابع به كار خود خاتمه ميدهد، مقادير متغيرهاي محلي آن از بين ميروند (در فصل ششم با متغيرهاي محلي آشنا خواهيد شد كه از اين قاعده مستثني هستند). از بخش 2-3 بخاطر داريد كه شيي كه داراي صفت است، آن را با خود همراه دارد و در برنامه از آن استفاده ميشود. چنين صفاتي در كل طول عمر يك شي وجود خواهند داشت.
معمولاً كلاسي كه داراي يك يا چندين تابع عضو است، مبادرت به دستكاري كردن صفات متعلق به يك شي مشخص از كلاسي ميكند. صفات به عنوان متغيرهاي در تعريف كلاس عرضه ميشوند. چنين متغيرهاي، بنام اعضاي داده شناخته ميشوند و در درون تعريف كلاس اعلان ميگردند اما در خارج از تعريف بدنه تابع عضو كلاس جاي ميگيرند. هر شي از كلاس مسئول نگهداري كپي از صفات متعلق به خود در حافظه است. مثال مطرح شده در اين بخش به توصيف كلاس ميپردازد كه حاوي يك عضو داده است تا نشاندهنده نام يك دوره خاص از شي باشد.
در اين مثال، كلاس (برنامه شكل 5-3) مبادرت به نگهداري نام دوره بصورت يك عضو داده ميكند و از اينروست كه ميتواند بكار گرفته شده يا در هر زمان اجراي برنامه آن را اصلاح كرد. كلاس حاوي توابع عضو ، و است. تابع عضو نام دوره را در عضو داده ذخيره ميسازد. تابع عضو نام دوره را از عضو داده بدست ميآورد. تابع عضو كه هيچ پارامتري ندارد، پيغام خوشآمدگويي را كه شامل نام دوره است، به نمايش در ميآورد. با اين همه، همانطوري كه مشاهده ميكنيد، در حال حاضر تابع، نام دوره را با فراخواني تابع ديگري در همان كلاس بدست ميآورد، تابع .
|
Initial course name is:
Please enter the course name:
Welcome to the grade book for CS101 Introduction to C++ Programming! |
يك خط خالي مابين تعريف تابع عضو قرار دهيد تا خوانايي برنامه افزايش پيدا كند.
معمولاً يك مدرس بيش از يك دوره را تدريس ميكند كه هر دوره داراي نام متعلق بخود است. در خط 39 ، متغير از نوع رشته اعلان شده است. بدليل اينكه متغير اعلان شده در درون تعريف كلاس اعلان شده (خطوط 15-40 ) اما در خارج از بدنه تعاريف توابع عضو جاي دارد (خطوط 19-22 ، 25-28 و 31-37 )، خط 39 اعلاني براي يك عضو داده است. هر نمونهاي (شي) از كلاس حاوي يك كپي از هر عضو داده كلاس خواهد بود. براي مثال، اگر دو شي وجود داشته باشد، هر شي داراي يك كپي از متعلق ب خ ود خواهد بود، همانطوري كه در مثال برنامه شكل 7-3 شاهد آن خواهيد بود. مزيت ايجاد بصورت يك عضو داده در اين است كه تمام توابع عضو يك كلاس (در اين مورد، ) ميتوانند در هر عضو داده موجود كه در تعريف كلاس وجود دارد، دستكاري كنند (در اين مورد، ).