باز هم سلام .
اين دوستمون dogtag يه خورده از دستم ناراحت بودن که ... .
براي همين يه پست ديگه هم ميدم در مورد چطوري سربارگذاري کنيم .
خوب براي سربارگذاري هر عملگر يه تابع مي نويسيم . اسم اين تابع هميشه بايد از کلمه کليدي operator به اضافه عملگر مورد نظر تشکيل بشه . تنها نکته اي که مي مونه اينه که اين تابع چي بايد برگردونه و چي بايد بگيره . اين هم که تقريبا راحته . شما يه بار عملگر رو تو ذهن خودتون مجسم کنين و ببينين وقتي کاربر تو جايي مي نويسه h1 == h2 ، که h1 و h2 اشيائي از کلاس شما هستن ، مي خواد که نتيجه يا True باشه يا False . يعني تابع سربارگذاري ما نبايد چيزي غير از اين برگردونه . بنابراين ما مي تونيم از نوع داده اي bool که فقط مي تونه true و يا false رو تو خودش نگه داره به عنوان نوع داده برگشتي تابع سربارگذاري عملگر == استفاده کنيم . بعد تو پياده سازي هم معين کنيم که کي true برگردونده بشه و کي false . اين عملگر به دو تا عملوند نياز داره . يکيش که همون خود شيئي است که اين تابع رو فراخواني کرده ، يعني this و يکيشو هم از طريق آرگومان براش مي فرستيم . در مورد عملگر =! به همين طور . ولي يه چيزي . شما وقتي == رو سربارگذاري کردين ، ديگه لازم نيست =! رو هم دوباره سربارگذاري کنين . مي تونين تو پياده سازي =! راحت بنويسين :
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
يعني هر چي عملگر == برگردوند ، =! خلاف اون رو برگردونه . ( ! علامت نقيض تو ++C هست . )
از اين کارا تو سربارگذاري عملگرهاي < و > و => و =< هم استفاده کنين .
مثلا فرض کنين عملگر > رو سربارگذاري کردين . اين تابع هم نتيجه اش يا true هست يا false . بنابراين براي نوع داده برگشتي اين تابع از bool استفاده ميکنيم . مثل == هم يه آرگومان ميگيره از نوع شيئي از خود کلاس . اين تابع رو پياده سازي مي کنيم . حالا سه عملگر بعدي به صورت زير به سادگي قابل سربارگذاري هستن :
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
حالا کاربر فرض کنين تو تابع main دو تا شيء به نام هاي h1 و h2 از کلاسمون گرفته و داره کاراي زير رو انجام ميده :
کد:
برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
تو اولي ميگيم آيا h1 کمتر از h2 هست ؟ تو اين جا انگار h1 داره تابع > رو فراخواني ميکنه . پس this همون h1 هست . يعني تو عملگرهاي دودويي ، هميشه عملگر سمت چپ به جاي this قرار مي گيره .
تابع سربارگذاري > فراخواني ميشه و بر اساس پياده سازيش يکي از دو مقدار true يا false رو برمي گردونه . فرض کنين true برگردونده شده . يعني h1 کوچکتر از h2 هست . حالا ميره خط 2 و مي گه آيا h1 يا this بزرگتر از h2 هست ؟ سربارگذاري عملگر بزرگتر به ما ميگه که اين تابع نتيجه تابع h2 < *this رو برميگردونه . که اين تابع false بر ميگردونه . چون h2 بزرگتر از this يا h1 بود . در مورد h1<= h2 هم تابع سربارگذاري اين عملگر ، نقيض عملگر < رو برميگردونه . يعني اگه بزرگتر نباشه پس حتما کوچکتر يا مساوي هست و به همين ترتيب ... .
مثلا فرض کنين مي خواين عملگر = رو سربارگذاري کنين . اين عملگر بايد شيء سمت راست خودش رو تو شيء سمت چپ يا this کپي کنه . پس يه شيء از خود کلاس ميگيره و يه شيء از خود کلاس برمي گردونه .
ضمنا يه نکته :
از عملگر = ميشه بدون سربارگذاري براي هر شيئي از کلاس هامون استفاده کرد . اين عملگر به طور اتوماتيک تک تک داده هاي عضو کلاس مون رو کپي مي کنه . اين کار در بيشتر مواقع کار مدنظر ماست . ولي اين کار تو بعضي جاها خيلي خطرناکه . مثلا جايي که شما يه داده عضو اشاره گر داشته باشين . مي دونين که اشاره گر حاوي آدرس يه متغير هست . بنابراين موقع کپي شدن آدرس کپي ميشه و اين مي تونه بعدا مشکلاتي جدي بوجود بياره . ( چون دو تا متغير داراي يه آدرس تو حافظه ميشن . )
در مورد istream و ostream سوال پرسيدين که من قبلا در موردشون بحث کرده بودم . istream يه کلاسه که تو کتابخانه استاندارد ++C تعريف شده و عمليات ورودي از صفحه کليد رو کنترل مي کنه و ما مي تونيم ازش استفاده کنيم . ostream هم يه کلاسه که تو کتابخانه استاندارد ++C تعريف شده و عمليات خروجي رو کنترل مي کنه و ما مي تونيم ازش استفاده کنيم . وقتي مي خوايم عملگرهاي ورودي و خروجي ( << و >> ) رو سربارگذاري کنيم ، اين توابع بايد يه istream يا ostream برگردونن .
ديگه نمي دونم باز هم مطالب گنگ هستن يا نه . ولي اگه گنگه باز هم بگين . من در خدمت هستم .