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

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

در مورد عملگرهایی که دو معنا دارن چطوری سربارگذاری کنیم؟

0 امتیاز
739 نمایش

عملگرهایی مانند - که هم می‌شه به عنوان یکانی (مثلاً در -a) در نظر گرفت هم دوتایی (مثلاً در a-b)، چطوری سربارگذاری رو مشخص کنیم. این که کدوم یکی مورد نظرمون هست؟

هیچ پژوهش انسانی نمی‌تواند ادعای علمی بودن داشته باشد، مگر این‌که از برهان ریاضی برخوردار باشد (لئوناردو داوینچی)
پرسیده شده جمعه ۳۰ فروردین ۱۳۹۲ در C++ توسط prodo  

مگه در مورد a- بصورت عملگر عمل میکنه؟
مثال دیگه‌ای هم دارین؟
و اینکه خب اگه اینجوری هم باشه چندشکلی بودن توابع (در مورد تعداد پارامتر ورودی) میتونه استفاده میشه. درست میگم؟

- هم می‌تونه به صورت عملگر یکانی در نظر گگرفته بشه هم دوتایی. مثل +.
نمی‌دونم می‌شه از چندریختی استفاده کرد یا نه

1 پاسخ

0 امتیاز

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

پیاده‌سازی به صورت تابع عضو
در این حالت عملگر یکانی به صورت [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);

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);

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

const T& operator+(); // عضو
T& operator+(); // عضو
const T& operator+(T& obj); // دوست
T& operator+(T& obj); // دوست
هیچ پژوهش انسانی نمی‌تواند ادعای علمی بودن داشته باشد، مگر این‌که از برهان ریاضی برخوردار باشد (لئوناردو داوینچی)
پاسخ داده شده شنبه ۱۸ خرداد ۱۳۹۲ توسط prodo  
ویرایش شده شنبه ۱۸ خرداد ۱۳۹۲ توسط prodo