اولین بار است که به این وب‌سایت می‌آیید. راهنما را مطالعه کنید!
x
موسسه خیریه محک

شهر ریاضی بازی-ریاضی

تاریخچه‌ی ویرایش برای ارسال #1659

شنبه ۱۸ خرداد ۱۳۹۲ ارسال شده توسط prodo

عملگر یکانی به صورت `[const] T operaotr+() [const]` (یا `[const] T operator-() [const]`) سربارگذاری می‌شه. `T` می‌تونه هر نوع داده‌ای باشه و حتی می‌تونه `void` باشه.
`const` قبل از امضای تابع مشخص می‌کنه که نوع بازگشتی به صورت `const` برگردونده بشه یا نه.
`const` پس از پرانتز آرگومان‌ها هم همون طور که مشخصه معلوم می‌کنه که تابع شی فراخواننده رو تغییر می‌ده یا نه.
یعنی همه‌ی امضاهای زیر درست هستند

void operator+() const;
void operator+();

T operator+();
T operator+() const;
const T operator+();
const T operator+() const;

T& operator();
const T& operator();
T& operator+() const;
const T& operator+() const;

T* operator+();
const T* operator();
T* operator+() const;
const T* operator+() const;

دو امضای زیر در صورتی که نیاز به برگشت `this` یا `*this` از تابع باشع درست نیستند

T& operator+() const;
T* operator+() const;
برای این که یک تابع عضو که قراره `const` باشه نمی‌تونه اشاره‌گری به خود شی برگردونه. مخالف با `const` اعلان کردن تابع هست. یعنی کد زیر اشتباهه

class C
{
private:
...
public:
C& operator+() const
{
...
return *this;
}
};
نکته این که `T` لازم نیست از نوع شی فراخواننده باشه. هر نوع دلخواهی می‌تونه باشه. مثلاً کد زیر درسته

class C
{
private:
...
public:
int operator+() const
{
...
return 0;
}
};
شنبه ۱۸ خرداد ۱۳۹۲ ویرایش شده توسط prodo

دو حالت کلی مساله رو در نظر می‌گیریم. پیاده‌سازی به صورت تابع عضو و پیاده‌سازی به صورت تابع دوست.

**پیاده‌سازی به صورت تابع عضو**
در این حالت عملگر یکانی به صورت `[const] T operaotr+() [const]` (یا `[const] T operator-() [const]`) سربارگذاری می‌شه. `T` می‌تونه هر نوع داده‌ای باشه و حتی می‌تونه `void` باشه.
`const` قبل از امضای تابع مشخص می‌کنه که نوع بازگشتی به صورت `const` برگردونده بشه یا نه.
`const` پس از پرانتز آرگومان‌ها هم همون طور که مشخصه معلوم می‌کنه که تابع شی فراخواننده رو تغییر می‌ده یا نه.
یعنی همه‌ی امضاهای زیر درست هستند

void operator+() const;
void operator+();

T operator+();
T operator+() const;
const T operator+();
const T operator+() const;

T& operator();
const T& operator();
T& operator+() const;
const T& operator+() const;

T* operator+();
const T* operator();
T* operator+() const;
const T* operator+() const;

دو امضای زیر در صورتی که نیاز به برگشت `this` یا `*this` از تابع باشع باشه درست نیستند

T& operator+() const;
T* operator+() const;
برای این که یک تابع عضو که قراره `const` باشه نمی‌تونه اشاره‌گری به خود شی برگردونه. مخالف با `const` اعلان کردن تابع هست. یعنی کد زیر اشتباهه

class C
{
private:
...
public:
C& operator+() const
{
...
return *this;
}
};
نکته این که `T` لازم نیست از نوع شی فراخواننده باشه. هر نوع دلخواهی می‌تونه باشه. مثلاً کد زیر درسته

class C
{
private:
...
public:
int operator+() const
{
...
return 0;
}
};

**پیاده‌سازی به صورت تابع دوست**
در این حالت `const` پس از پرانتز آرگومان‌ها مفهوم پیدا نمی‌کنه. امضاهای ممکن به شکل `[const] T2 operator+([const] T)` هستند.
`T` شی‌ای از کلاس، یا ارجاع یا اشاره‌گری به شی‌ای از کلاس هست و `T2` یک نوع داده‌ی دلخواه که می‌تونه `void` یا هر نوع داده‌ی دلخواه دیگه‌ای باشه.

void operator+(T obj);
void operator+(const T obj);
void operator+(T &obj);
void operator+(const T &obj);
void operator+(T *obj);
void operator+(const T *obj);

T operator+(T obj);
T operator+(const T obj);
T operator+(T &obj);
T operator+(const T &obj);
T operator+(T *obj);
T operator+(const T *obj);

T& operator+(T obj);
T& operator+(const T obj);
T& operator+(T &obj);
T& operator+(const T &obj);
T& operator+(T *obj);
T& operator+(const T *obj);

T* operator+(T obj);
T* operator+(const T obj);
T* operator+(T &obj);
T* operator+(const T &obj);
T* operator+(T *obj);
T* operator+(const T *obj);

const T& operator+(T obj);
const T& operator+(const T obj);
const T& operator+(T &obj);
const T& operator+(const T &obj);
const T& operator+(T *obj);
const T& operator+(const T *obj);

const T* operator+(T obj);
const T* operator+(const T obj);
const T* operator+(T &obj);
const T* operator+(const T &obj);
const T* operator+(T *obj);
const T* operator+(const T *obj);
در میان این امضاها هم مواردی هستند که در صورت برگردوندن اشاره‌گر یا آدرس شی فراخواننده نمی‌تونن استفاده بشن. این موارد اون‌هایی هستند که شی رو به صورت `const` دریافت می‌کنن و به صورت غیر `const` برمی‌گردونن. یعنی موارد زیر

T& operator+(const T obj);
T& operator+(const T &obj);
T& operator+(const T *obj);

T* operator+(const T obj);
T* operator+(const T &obj);
T* operator+(const T *obj);
شنبه ۱۸ خرداد ۱۳۹۲ ویرایش شده توسط prodo

در دو حالت کلی مساله رو در نظر می‌گیریم. پیاده‌سازی به صورت تابع عضو و پیاده‌سازی به صورت تابع دوست.

**پیاده‌سازی به صورت تابع عضو**
در این حالت عملگر یکانی به صورت `[const] T operaotr+() [const]` (یا `[const] T operator-() [const]`) سربارگذاری می‌شه. `T` می‌تونه هر نوع داده‌ای باشه و حتی می‌تونه `void` باشه.
`const` قبل از امضای تابع مشخص می‌کنه که نوع بازگشتی به صورت `const` برگردونده بشه یا نه.
`const` پس از پرانتز آرگومان‌ها هم همون طور که مشخصه معلوم می‌کنه که تابع شی فراخواننده رو تغییر می‌ده یا نه.
یعنی همه‌ی امضاهای زیر درست هستند

void operator+() const;
void operator+();

T operator+();
T operator+() const;
const T operator+();
const T operator+() const;

T& operator();
const T& operator();
T& operator+() const;
const T& operator+() const;

T* operator+();
const T* operator();
T* operator+() const;
const T* operator+() const;

دو امضای زیر در صورتی که نیاز به برگشت `this` یا `*this` از تابع باشه درست نیستند

T& operator+() const;
T* operator+() const;
برای این که یک تابع عضو که قراره `const` باشه نمی‌تونه اشاره‌گری به خود شی برگردونه. مخالف با `const` اعلان کردن تابع هست. یعنی کد زیر اشتباهه

class C
{
private:
...
public:
C& operator+() const
{
...
return *this;
}
};
نکته این که `T` لازم نیست از نوع شی فراخواننده باشه. هر نوع دلخواهی می‌تونه باشه. مثلاً کد زیر درسته

class C
{
private:
...
public:
int operator+() const
{
...
return 0;
}
};

**پیاده‌سازی به صورت تابع دوست**
در این حالت `const` پس از پرانتز آرگومان‌ها مفهوم پیدا نمی‌کنه. امضاهای ممکن به شکل `[const] T2 operator+([const] T)` هستند.
`T` شی‌ای از کلاس، یا ارجاع یا اشاره‌گری به شی‌ای از کلاس هست و `T2` یک نوع داده‌ی دلخواه که می‌تونه `void` یا هر نوع داده‌ی دلخواه دیگه‌ای باشه.

void operator+(T obj);
void operator+(const T obj);
void operator+(T &obj);
void operator+(const T &obj);
void operator+(T *obj);
void operator+(const T *obj);

T operator+(T obj);
T operator+(const T obj);
T operator+(T &obj);
T operator+(const T &obj);
T operator+(T *obj);
T operator+(const T *obj);

T& operator+(T obj);
T& operator+(const T obj);
T& operator+(T &obj);
T& operator+(const T &obj);
T& operator+(T *obj);
T& operator+(const T *obj);

T* operator+(T obj);
T* operator+(const T obj);
T* operator+(T &obj);
T* operator+(const T &obj);
T* operator+(T *obj);
T* operator+(const T *obj);

const T& operator+(T obj);
const T& operator+(const T obj);
const T& operator+(T &obj);
const T& operator+(const T &obj);
const T& operator+(T *obj);
const T& operator+(const T *obj);

const T* operator+(T obj);
const T* operator+(const T obj);
const T* operator+(T &obj);
const T* operator+(const T &obj);
const T* operator+(T *obj);
const T* operator+(const T *obj);
در میان این امضاها هم مواردی هستند که در صورت برگردوندن اشاره‌گر یا آدرس شی فراخواننده نمی‌تونن استفاده بشن. این موارد اون‌هایی هستند که شی رو به صورت `const` دریافت می‌کنن و به صورت غیر `const` برمی‌گردونن. یعنی موارد زیر

T& operator+(const T obj);
T& operator+(const T &obj);
T& operator+(const T *obj);

T* operator+(const T obj);
T* operator+(const T &obj);
T* operator+(const T *obj);

**بهترین انتخاب** بستگی به مورد استفاده هر کدوم از این امضاها می‌تونن استفاده شن. اما به طور کلی اگه خود شی فراخواننده در انتها برگردونده می‌شه بهتره از یکی از شکل‌هایی زیر استفاده کنیم

const T& operator+(); // عضو
T& operator+(); // عضو
const T& operator+(T& obj); // دوست
T& operator+(T& obj); // دوست
شنبه ۱۸ خرداد ۱۳۹۲ ویرایش شده توسط prodo

در دو حالت کلی مساله رو در نظر می‌گیریم. پیاده‌سازی به صورت تابع عضو و پیاده‌سازی به صورت تابع دوست.

**پیاده‌سازی به صورت تابع عضو**
در این حالت عملگر یکانی به صورت `[const] T operaotr+() [const]` (یا `[const] T operator-() [const]`) سربارگذاری می‌شه. `T` می‌تونه هر نوع داده‌ای باشه و حتی می‌تونه `void` باشه.
`const` قبل از امضای تابع مشخص می‌کنه که نوع بازگشتی به صورت `const` برگردونده بشه یا نه.
`const` پس از پرانتز آرگومان‌ها هم همون طور که مشخصه معلوم می‌کنه که تابع شی فراخواننده رو تغییر می‌ده یا نه.
یعنی همه‌ی امضاهای زیر درست هستند

void operator+() const;
void operator+();

T operator+();
T operator+() const;
const T operator+();
const T operator+() const;

T& operator();
const T& operator();
T& operator+() const;
const T& operator+() const;

T* operator+();
const T* operator();
T* operator+() const;
const T* operator+() const;

دو امضای زیر در صورتی که نیاز به برگشت `this` یا `*this` از تابع باشه درست نیستند

T& operator+() const;
T* operator+() const;
برای این که یک تابع عضو که قراره `const` باشه نمی‌تونه اشاره‌گری به خود شی برگردونه. مخالف با `const` اعلان کردن تابع هست. یعنی کد زیر اشتباهه

class C
{
private:
...
public:
C& operator+() const
{
...
return *this;
}
};
نکته این که `T` لازم نیست از نوع شی فراخواننده باشه. هر نوع دلخواهی می‌تونه باشه. مثلاً کد زیر درسته

class C
{
private:
...
public:
int operator+() const
{
...
return 0;
}
};

**پیاده‌سازی به صورت تابع دوست**
در این حالت `const` پس از پرانتز آرگومان‌ها مفهوم پیدا نمی‌کنه. امضاهای ممکن به شکل `[const] T2 operator+([const] T)` هستند.
`T` شی‌ای از کلاس، یا ارجاع یا اشاره‌گری به شی‌ای از کلاس هست و `T2` یک نوع داده‌ی دلخواه که می‌تونه `void` یا هر نوع داده‌ی دلخواه دیگه‌ای باشه.

void operator+(T obj);
void operator+(const T obj);
void operator+(T &obj);
void operator+(const T &obj);

void operator+(T *obj);
void operator+(const T *obj);

T operator+(T obj);
T operator+(const T obj);
T operator+(T &obj);
T operator+(const T &obj);
T operator+(T *obj);
T operator+(const T *obj);

T& operator+(T obj);
T& operator+(const T obj);
T& operator+(T &obj);
T& operator+(const T &obj);
T& operator+(T *obj);
T& operator+(const T *obj);

T* operator+(T obj);
T* operator+(const T obj);
T* operator+(T &obj);
T* operator+(const T &obj);
T* operator+(T *obj);
T* operator+(const T *obj);

const T& operator+(T obj);
const T& operator+(const T obj);
const T& operator+(T &obj);
const T& operator+(const T &obj);
const T& operator+(T *obj);
const T& operator+(const T *obj);

const T* operator+(T obj);
const T* operator+(const T obj);
const T* operator+(T &obj);
const T* operator+(const T &obj);
const T* operator+(T *obj);
const T* operator+(const T *obj);
T operator+(T obj);
T operator+(const T obj);
T operator+(T &obj);
T operator+(const T &obj);

T& operator+(T obj);
T& operator+(const T obj);
T& operator+(T &obj);
T& operator+(const T &obj);

T* operator+(T obj);
T* operator+(const T obj);
T* operator+(T &obj);
T* operator+(const T &obj);

const T& operator+(T obj);
const T& operator+(const T obj);
const T& operator+(T &obj);
const T& operator+(const T &obj);

const T* operator+(T obj);
const T* operator+(const T obj);
const T* operator+(T &obj);
const T* operator+(const T &obj);

در میان این امضاها هم مواردی هستند که در صورت برگردوندن اشاره‌گر یا آدرس شی فراخواننده نمی‌تونن استفاده بشن. این موارد اون‌هایی هستند که شی رو به صورت `const` دریافت می‌کنن و به صورت غیر `const` برمی‌گردونن. یعنی موارد زیر

T& operator+(const T obj);
T& operator+(const T &obj);

T& operator+(const T *obj);

T* operator+(const T obj);
T* operator+(const T &obj);
T* operator+(const T *obj);

T* operator+(const T obj);
T* operator+(const T &obj);

**بهترین انتخاب** بستگی به مورد استفاده هر کدوم از این امضاها می‌تونن استفاده شن. اما به طور کلی اگه خود شی فراخواننده در انتها برگردونده می‌شه بهتره از یکی از شکل‌هایی زیر استفاده کنیم

const T& operator+(); // عضو
T& operator+(); // عضو
const T& operator+(T& obj); // دوست
T& operator+(T& obj); // دوست