PDA

View Full Version : دلیل pass-by-ref نوشتن خروجی



fshb_ 1370
چهارشنبه 26 مرداد 1390, 13:21 عصر
ی تابع friend دارم ک در اون >> را overload کردم. ولی در کتاب نوشته بود که حتما ostream حتما باید pass-by-ref باشه. دلیلش چیه؟؟ چرا باید آرگومان t از نوع Time از نوع pass-by-ref و const باشه؟؟

class Time
{
private:
int minuts;
int hours;
public:
friend ostream & operator<<(ostream &os, const Time &t);
};

ostream & operator<<(ostream &os, const Time &t)
{
os<<t.hours<<" hours, "<<t.minuts<<" minuts.";
return os;
}

_hamid
چهارشنبه 26 مرداد 1390, 16:14 عصر
در اصل این بخاطر اینه :
return os;
چرا؟‌ چون اگر os رو به صورت reference نباشه خط بالایی ادرس یه متغییر local رو می فرسته که وقتی اجرا بشه و تموم بشه اون متغییر از بین میره پس return اشباه در میاد!
اما در مورد آرگومان دومی یعنی time &t من فکر نمی کنم در این مورد لازم باشه با reference پاس بدیش! با مقدار هم مشکلی پیش نمیاد. ولی اگر object که داری با مقدار پاس میدش بزرگ باشه خوب یه کپی الکی انجام دادی!

fshb_ 1370
جمعه 28 مرداد 1390, 10:17 صبح
در اصل این بخاطر اینه :
return os;
چرا؟‌ چون اگر os رو به صورت reference نباشه خط بالایی ادرس یه متغییر local رو می فرسته که وقتی اجرا بشه و تموم بشه اون متغییر از بین میره پس return اشباه در میاد!

میشه ی خورده بیشتر توضیح بدید؟؟ من درست متوجه نشدم.
int test(int x)
{
return x;
}
مثلا کد بالا که مقدار x رو return میکنه، x به تابع main که تابع test صدا زده نمیرسه؟!!!!

_hamid
جمعه 28 مرداد 1390, 10:54 صبح
مثال خود یه کوچولو با کدمون فرق داره.
به کد(اینجا تابع) دقت کن.
اول ببین چجوری و از چه نوعی تعریف شده( فرقی بین یه تابع و سربارگذاری وجود نداره مگر شکلش):
ostream & operator<<(ostream &os, const Time &t)
خوب اینجا مثل همون مثال تست خودته اما این شکلی:
int & test(int &x){
return x;
}

به نظرت چی الان بر می گرده؟ یک ارجاع از آرگومانمون.
چرا؟ بخاطر اینکه نوع مقدار برگردانده شده تابع اینجوری تعریف شده int & test .
اما اگر بخواییم مثل مثال خودت(test) کد بزنیم این جوری میشه:
هر وقت که تابع رو تعریف می کنیم یک کپی از آرگومانمون درست میشه ( ارجاع با مقدار ) و این کپی میشه یک مقدار محلی(local) که اگر تابع به پایان برسه اونم میمیره (‌می تونی با یه کلاس که سازنده و مخرب داره تست کنی ).
اینجا همون مسکلی پیش میاد که اگر os رو به صورت reference تعیین نکنی پیش میاد( این با مثال خودت یه ذره فرق داره):
int & test(int x){
return x;
}

ارجاع از متغییر محلی ( در اینجا کپی ایجاد شده از آرگومان) برگشت(return) داده میشود که وقتی تابع به پایان رسیده از بین رفته.
---
حالا به نظرت چرا اصلا اون return os لازمه؟
ما قراره که با کلاسمون اینجوری برخورد کنیم دیگه:
Time t;
cout <<t;
اگر اون return os نباشه ما نمی تونیم اینجوری کد بزنیم :
cout << t << t << t;