کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنیدکد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنیدکد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
محتوای مخفی: Relationship between Base Classes and Derived Classes
محتوای مخفی: Constructors and Destructors in Derived Classes
مونا خانوم، (حدس زدم!) شما هم که کثیف کار تر از همه!
خب همین رو بهش 1 نظم می دادید، می شد یه پست 100% مفید.
البته این هم 80% مفیده.
ممنون از این که گذاشتید.
کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اگه میتونی 10 مگ دانلود کنی بگو تا خود کتابو بذارم تا کثیف کاری نشه![]()
شکر خدا یه 128 دارم که گاهی اوقات قاطی می کنه و میشه 512!
ولی اگر 56K ذغالی هم داشتم، 10 مگ چیزی نبود!
مرسی
Polymorphism
چندريختي يا Polymorphism در واقع نوعي استفاده از قابليت ارث بري در برنامه نويسي شيء گرا است .
کلاس پايه Animal رو در نظر بگيرين . سه کلاس Fish ، Frog و Bird از اين کلاس به ارث رسيدن ( مشتق شدن ) . مي خوايم براي حرکت اين حيوانات برنامه اي بنويسيم . هر حيوان ( قورباغه ، ماهي و پرنده ) حرکت خاص خودشو داره . مثلا قورباغه براي حرکت مي پره ، ماهي شنا مي کنه و پرنده پرواز مي کنه . کلاس Animal هم فرض کنيد راه مي ره . هر چهار تاي اين کلاس ها داراي تابع عضوي به نام move هستن .
مي خوايم براي اين تابع از خاصيت چندريختي استفاده کنيم . براي اين منظور بايد قبل از نوع داده برگشتي اين تابع کلمه virtual رو قرار بديم . مثلا :
براي استفاده از چندريختي ، يه اشاره گر به کلاس پايه تعريف مي کنيم .کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
حالا مي تونيم آدرس کلاس مشتق رو تو اشاره گر کلاس پايه قرار بديم . به شکل زير :کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
حالا اگه تابع move کلاس پايه رو فراخواني کنيم ، تابع move مربوط به کلاس قورباغه احضار ميشه .کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اما اگه از کلمه کليدي virtual استفاده نکرده بوديم ، کماکان تابع move کلاس Animal احضار مي شد . استفاده از کلمه virtual به کامپايلر ميگه که در زمان اجرا تعيين کنه که کدوم اشاره گر حاوي چه آدرسي هست نه در زمان کامپايل .
به تابع move مي گيم تابع مجازي يا virtual . يه مفهوم ديگه هم که تو Polymorphism وجود داره ، مجازي محض يا pure virtual هست . با يه مثال اينو هم توضيح مي دم .
فرض کنين داريم يه برنامه براي بازي شطرنج مي نويسيم . اسب و فيل و سرباز و ... همه از کلاس پايه اي به نام Mohreh به ارث رسيدن . هر کدوم از کلاس هاي اسب و فيل و سرباز و ... داراي تابع move منحصر بفرد هستن . چون شيوه حرکت هيچ مهره اي شبيه به هم نيست . ولي کلاس پايه ما هم داراي تابع move هست . براي اين کلاس چجوري تابع move رو پياده سازي کنيم ؟ معلوم نيست که منظور از Mohreh چيه . حرکتي براي اين کلاس نمي تونيم تعيين کنيم . بنابراين بايد تابع move رو pure virtual تعريف کنيم . کافيه در کلاس پايه ، تابع move رو مساوي صفر قرار بديم .
اين تابع رو ديگه پياده سازي نمي کنيم .کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
نکته : به هر کلاسي که حداقل يه تابع مجازي محض داشته باشه ميگيم کلاس تجريدي يا Abstract Class . از کلاس تجريدي نمي توان شيئي نمونه سازي کرد .
اين Polymorphism خيلي کاربرد داره . مثلا من قبلا که داشتم پروژه شطرنج رو مي نوشتم اين چندريختي خيلي کمک کرد . بدون اون يه کم سخته . همچنين باعث ميشه ظاهر برنامه استاندارد به نظر برسه .
تو پست بعدي مثال هم ميارم . ! جناب dogtag !
ببخشيد که اين روزا کم ميام و فاصله بين پست ها زياد ميشه .
فکر کنم قبلا کلاس Account رو براي ارث بري مثال زده بودم . حالا هم اونو تغيير دادم براي Polymorphism .
اول کد برنامه رو مي ذارم بعد يه چيزايي شبيه توضيح مي دم .
کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنیدکد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنیدکد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنیدکد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنیدخوب ...کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
بله ..... اولين قطعه کد ، هدر کلاس پايه مون هست . چهار تا تابع عضو داره . اولي Constructor هست که يه پارامتر از نوع double داره . بعد سه تا تابع ديگه داره که اولي Virtual و دو تاي بعدي pure virtual هستن . يدونه هم داده عضو داره که به صورت protected تعريف شده تا توسط کلاس هاي مشتق از اين کلاس ، يعني SavingsAccount قابل دسترسي باشه . قطعه کد بعدي پياده سازي اين کلاس رو نشون ميده . مي بينين که توابع pure virtual پياده سازي نشدن .
قطعه کد سوم هدر يه کلاس به نام SavingsAccount هست که از کلاس Account به ارث رسيده . يه سازنده داره .
دو تا نکته اين جا هست . يکيش اينه که مي بينين توابع credit و debit و print دوباره تو کلاس مشتق پياده سازي شدن . به اين کار Override کردن تابع مي گن . نکته دوم اينه که گذاشتن کلمه کليدي virtual در کنار توابع عضو کلاس مشتق اختياره . چون تو کلاس پايه اين کار انجام شده و تا آخر اين توابع virtual تعريف شدن . اين کلاس دو تا تابع عضو اضافي + يه داده عضو ديگه داره . قطعه کد بعدي پياده سازي اين کلاس رو نشون مي ده .
........
حالا کار تو تابع main هستش .
ببينين کلاس Account ما يه کلاس Abstract هست .
چرا ؟
آفرين ... چون حداقل يه تابع pure virtual داره . بنابراين نمي تونيم ازش شيئي بگيريم .
ما قراره آدرس هاي اشياء کلاس مشتق رو تو اشاره گر هاي کلاس پايه قرار بديم و از طريق اين اشاره گر ها توابع کلاس مشتق رو فراخواني کنيم .
من در اينجا از vector استفاده کردم تا با اون هم آشنا بشين . براي استفاده از vector ، اونو اول include مي کنيم .
يه شيء از کلاس مشتق نمونه سازي مي کنيم . ( توجه داريد که کلاس مشتق ما Abstract نيست . ) دستور خط بعدي آرايه اي از اشاره گرهاي کلاس پايه رو ايجاد ميکنه . ما اينجا آرايه رو يک عضوي در نظر گرفتيم . بعد آدرس کلاس مشتق رو درون اشاره گر کلاس پايه قرار ميديم و توابع عضو credit و debit و print رو فراخواني مي کنيم . در اينجا توابع مربوط به کلاس مشتق فراخواني ميشه .
با سلام خدمت دوستان عزيز و محترمي که تا اينجا ما رو همراهي کردن و هر کدوم به نحوي روحيه ادامه رو در بنده تقويت کردن .
قبلا يه فهرستي به پيشنهاد جناب CppBuilder2006 داده بودم . فقط نمي دونم چرا يادم رفته بود و template ها رو نذاشته بودم . ولي من اينجا در مورد اون هم توضيح مي دم . اگه template ها رو هم بگم بنا به عهدي که گذاشته بوديم مطالب زير مي مونه ( با توجه به اينکه قبلا راجع به اشاره گرها بحث شده بود ) :
1- توابع بازگشتي
2- کار با فايل ها
3- ساختمان داده ها
4- کلاس string
Template يا قالب
يه قالب تابعي داريم يه قالب کلاسي .
حالا اصلا قالب يا Template چي هست ؟
مثلا فرض کنين يه تابع داريم که يه آرايه از int ها رو مي گيره و ميانگين اونا رو به صورت يه int ديگه برمي گردونه . خوب حالا اگه براي اين تابع ما يه نوع داده ديگه غير از int بفرستيم ، مثلا double ، اين تابع نمي تونه کارشو انجام بده . يعني اين تابع ما فقط براي نوع خاصي از داده ها جواب مي ده . براي اينکه اين تابع براي همه انواع داده اي جواب داشته باشه از قالب ها استفاده مي کنيم . يه مثال کوچولو مي زنم .
تو سطر سوم اين قطعه کد دو کلمه کليدي template و typename رو ميبينين . وقتي قبل از يه تابعي از اين خط استفاده کنيم به کامپايلر ميگيم که تابع مربوطه حاوي يه نوع داده اي قالبي به نام arrTemp هست . به جاي typename مي تونيم از کلمه کليدي class نيز استفاده کنيم . يعني دو خط زير هيچ فرقي با هم ندارن :کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
بعد تو تابع هم مي بينين که به جاي استفاده از نوع داده اي خاص از arrTemp استفاده کرديم . تو تابع main هم انواع مختلف داده اي رو براي تابع average فرستاديم و براي ما جواب آورده .کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
اين يه مثال براي قالب تابعي بود .
حالا در مورد قالب کلاسي :
اول يه مثال مي زنم . به طريقه استفاده از قالب در مورد اين کلاس توجه کنين :
اول از همه قالب کلاس T رو براي کل کلاس تعريف کرديم .کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
بعد تعريف کلاس و Constructor و Destructor رو مي بينين .
تابع push و pop رو مي بينين . توابعي که به ترتيب مقداري رو در پشته يا Stack مي ذارن و برميدارن .چون از قالب ها مي خوايم استفاده کنيم و اين مقداري رو که مي ذاريم و برميدارم همه انواع داده اي رو ساپورت کنه از قالب T استفاده ميکنيم . تو قسمت داده هاي عضو هم يه اشاره گر مي بينين که از نوع T تعريف شده . دليل چيه ؟
ببينين اين Stack ما آرايه اي رو شامل مي شه که سايز اون در زمان اجرا توسط کاربر تعيين ميشه . بنابراين ما نياز به يه اشاره گر داريم که ازش براي تخصيص پوياي حافظه استفاده کنيم . چون مي خوايم اين آرايه همه انواع داده اي رو پشتيباني کنه باز از T استفاده مي کنيم . توجه داريد که داده هاي عضو size و pop هميشه يه عدد صحيح رو ذخيره مي کنن و نياز به استفاده از T نيست .
در ادامه اون پياده سازي کلاس اومده . براي هر 3 تابع مي بينين که دوباره تعريف قالب رو آورديم . يعني اين جور نيست که يه بار بگيم T قالبه و براي همه توابع استفاده کنيم . بايد قبل از هر تابع ، قالب مورد استفاده در اونو مشخص کنيم .
يه مورد ديگه اي هم که هست اينه که مي بينين به جاي استفاده از نام کلاس قبل از عملگر دو تا دو نقطه ، از <Stack<T استفاده کرديم .
تابع main زياد مهم نيست . فقط به خط
توجه کنين که يه Stack پنج عضوي از نوع double رو چجوري ايجاد کرديم .کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
کد:برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
هم اکنون 1 کاربر در حال مشاهده این تاپیک میباشد. (0 کاربر عضو شده و 1 مهمان)