سربارگذاری عملگرها در ++C

آشنایی با مفهوم سربارگذاری عملگرها در زبان ++C

✤    ۱۶ خرداد ۱۳۸۸ ، نوشته آذر ماه ۱۳۸۵ با عنوان «سربارگذاری عملگرها (در دو بخش)» از وب‌سایت برنامه‌نویسی و طراحی الگوریتم منتشر شده بود.

همانطور که می‌دانید، شیوه معرفی اشیاء کلاس‌های تعریف شده در ++C همانند متغیرهای عادی هستند. به عنوان مثال اگر کلاسی به نام myclass تعریف کرده باشیم، عبارت زیر یک شیء از این کلاس به نام a تعریف می‌کند:

  

myclass a;

  

اما اشیاء کلاس یک تفاوت اساسی با متغیرهای معمولی (مانند int ،float ،char و ...) دارند و آن عدم پشتیبانی از عملگرها است. در واقع عملگر انتساب (=) تنها عملگر قابل استفاده برای اشیاء کلاس است. اشیاء کلاس به صورت پیش‌فرض از عملگرهای دیگر (همانند + ، - ، / ، >> ، & و * و ...) پشتیبانی نمی‌کنند. اگر b ،a‌ و c سه شیء از کلاس myclass باشند، عبارت زیر کامپایل نمی‌شود:

  

c = a + b;

  

چرا که عمل جمع برای این اشیاء مفهومی ندارد. مگر اینکه خودمان زحمت مفهوم دادن به این عملگر را با استفاده از سربارگذاری عملگرها بکشیم. در واقع سربارگذاری به ما این امکان را می‌دهد که عملکرد هر عملگر را برای کلاس مشخص کنیم.

توجه داشته باشید که اگر کلاس ما حاوی دستوراتی برای تخصیص حافظه باشد، حتی عملگر انتساب پیش‌فرض هم قابل استفاده نیست. به قطعه کد زیر توجه کنید:

  

class myclass {

    char *str;

  public:

    myclass(int n) {

      str = new char[n];

    }

    ~myclass() {

      delete[] str;

    }

    .

    .

    .

};

  

اگر a و b دو شیء از این کلاس باشند، عبارت زیر یک خطای منطقی بسیار بزرگ را به دنبال دارد:

  

a = b;

  

در وهله اول به نظر می‌آید که این عبارت مشکلی نداشته باشد. اما اینطور نیست. حین عمل انتساب، محتویات اشاره‌گر str مربوط به شیء b به همتای خودش در شیء a کپی می‌شود. این عمل باعث بروز دو مشکل می‌شود: اولا محتویات اشاره‌گر str شیء a (و در واقع آدرس حافظه پویای اختصاص پیدا کرده توسط شیء a) از دست می‌رود که متعاقب آن نمی‌توان حافظه اختصاصی را آزاد کرد. ثانیا a و b از حافظه مشترک استفاده می‌کنند که به احتمال بسیار زیاد باعث ایجاد اختلال در برنامه خواهد شد.

همین مثال ساده نشان می‌دهد استفاده از سربارگذاری عملگرها از بروز چه مشکلاتی جلوگیری می‌کند. شما با تعریف مجدد عملگر انتساب برای این کلاس می‌توانید از بروز خطا جلوگیری کنید.

فرض کنید کلاسی داریم به نام complex که برای کار با اعداد مختلط ایجاد شده است. این کلاس می‌تواند به صورت زیر تعریف شده باشد:

  

class complex {

  private:

    double r, i ;

  public:

    complex(int a = 0, int b = 0) {

      r = a;

      i = b;

    }

};

  

این کلاس دو متغیر خصوصی دارد که برای ذخیره کردن قسمت حقیقی (r) و موهومی (i) عدد مختلط به کار می‌روند.

حال می‌خواهیم عملگر جمع را برای این کلاس تعریف کنیم.

  

complex operator + (const complex &b) {

  complex temp;

  temp.r = this->r + b.r;

  temp.i = this->i + b.i;

  return temp;

}

  

این تعریف ساده، عملگر + را برای جمع زدن دو عدد مختلط تعریف می‌کند. البته با این تعریف، کار سربارگذاری کامل عملگر + برای اعداد مختلط تمام نمی‌شود. ممکن است بخواهیم یک عدد حقیقی (یعنی متغیرهای معمولی ++C مانند int ،float و . . .) را با عدد مختلط جمع کنیم. تابع فوق تنها می‌تواند دو شیء از کلاس complex را با هم جمع کند و نه بیشتر.

این تابع یک ورودی دارد و یک خروجی. تکلیف خروجی تابع کاملا مشخص است. حاصل جمع دو عدد مختلط یک عدد مختلط است. پس تابع جمع، یک شیء از نوع complex را بر می‌گرداند. اما بر خلاف تصور اولیه ما، این تابع فقط یک ورودی دارد. در حالی که ما دو شیء را با هم جمع می‌کنیم. در واقع تابع جمع توسط شیء سمت چپ عملگر فراخوانی و شیء سمت راست به عنوان پارامتر به تابع ارسال می‌شود. به عنوان مثال فرض کنید که دو شیء c1 و c2 از کلاس complex در اختیار داریم. وقتی کامپایلر به عبارتی مانند c1 + c2 بر می‌خورد، آن را به صورت زیر تفسیر می‌کند:

  

c1.operator + (c2)

  

به همین خاطر برای دسترسی به اعضای شیء سمت چپ (در اینجا c1) باید از اشاره‌گر ضمنی this استفاده کنیم. تابع جمع بالا به غیر از مواردی که بحث کردم مورد دیگری ندارد.

تابع فوق فقط برای جمع دو شیء از کلاس complex کاربرد دارد. حالت دیگری که ممکن است به وجود بیاد، جمع کردن یک متغیر معمولی ++C با اشیاء این کلاس است. همانطور که می‌دانید عمل جمع بین اعداد مختلط و حقیقی تعریف شده است. هر عدد حقیقی یک عدد مختلط با قسمت موهومی صفر است. این حالت خود به دو صورت اتفاق می‌افتد: عدد سمت چپ مختلط و عدد سمت راست حقیقی باشد، یا عدد سمت چپ حقیقی و عدد سمت راست مختلط باشد. حالت دوم نیاز به آشنایی با توابع دوست کلاس دارد. اما برای حالت اول می‌توانیم از تابع زیر استفاده کنیم:

  

complex operator + (double x) {

  complex temp;

  temp.r = this->r + x ;

  temp.i = this->i ;

  return temp ;

}

  

تابع بالا دقیقا مانند تابع اولی تعریف شده است. با این تفاوت که پارامتر ورودی آن از شیء complex به متغیر از نوع double تغییر پیدا کرده است. به عنوان مثال عبارت c1 + 2.5 به این صورت تفسیر می‌شود:

  

c1.operator + (2.5)

  

به همین راحتی عملگر + برای اعداد مختلط تعریف شد. البته باید به نکات مهم زیر توجه کنید:

1- هنوز حالتی را که عملوند سمت چپ یک متغیر غیر مختلط باشد بررسی نکرده‌ایم.

2- در تابع دوم لزومی ندارد که عدد ورودی حتما اعشاری باشد. ++C از تغییر موقت متغیر برای امکان استفاده از اعداد صحیح پشتیبانی می‌کند.

3- دو تابع مذکور بدون هیچ مشکلی می‌توانند هم‌زمان در یک کلاس تعریف شوند. ++C از سربارگذاری توابع (تعریف چند تابع با یک نام، اما با پارامترهای متفاوت) پشتیبانی می‌کند.

4 - تعاریف بالا تعریف عملگر جمع پیش فرض ++C را مخدوش نمی‌کند. یعنی برای جمع دو عدد صحیح یا اعشاری هیچ مشکلی ایجاد نمی‌کند.

5- علت استفاده از const و متغیر مرجع در پارامتر تابع اول مربوط به کاربرد متغیرهای مرجع است که قبلا در این مورد مطلبی نوشته‌ام.

6- در تعاریف بالا لزومی به استفاده از اشاره‌گر ضمنی this وجود ندارد. اما برای خوانایی بیشتر کد معمولا از این روش استفاده می‌شود. دو عبارت this->r و r با هم معادل هستند.

7- توابع سربارگذاری عملگرها حتما باید در قسمت public کلاس تعریف شوند.

  

+

-

*

/

%

^

&

|

~

!

=

<

>

+=

-=

*=

/=

%=

^=

&=

|=

<<

>>

>>=

<<=

==

!=

<=

>=

&&

||

++

--

->*

,

->

[]

()

new

delete

new []

delete []

عملگرهایی را که می‌توان مجددا تعریف کرد


تا کنون ۴۳ امتیاز ثبت شده
نوشته لایک نداشت؟
 
به اشتراک گذاری نوشته

algs.ir/spk5tfd

اشتراک‌گذاری در LinkedIn     اشتراک‌گذاری در Twitter     ارسال با Telegram


نام: *

پست الکترونیک (محرمانه):

پیام: *

• Saba
۱۰ دی ۱۳۸۵، ساعت ۱۰:۴۸

سلام

اطلاعات کاملی در مورد سربارگذاری عملگرها در جاوا و #C میخواستم.

مرسی(:

• mahdiye
۲۴ فروردین ۱۳۸۹، ساعت ۱۹:۵۳

02

salam mamnoon az matalebi ke gozashtin

mishe class be c++  programing :

تاریخ

درس

student

اعداد مختلط

دایره

مستطیل

کتاب

اعداد کسری

خیلی فوریه !!!!!!!!!!!!!!!!

• سارا
۱۴ اردیبهشت ۱۳۸۹، ساعت ۲۱:۵۴

سلام در صورت امکان لطفا سربارگذاری تمامی عملگرهارو برای اعداد گویا بنویسید

• محمد
۲۰ خرداد ۱۳۸۹، ساعت ۱۰:۲۳

خواهشا کمکم کنید تا در ++c کلاسی تعریف کنم و در اون عملگرهای +و-و* را برای عملیات روی ماتریس ها مجددا تعریف کنم.مرسی.

• مریم
۹ مهر ۱۳۸۹، ساعت ۰۱:۲۶

ممنون

خیلی جامع و خوب نوشتید..

• ali
۲۵ آذر ۱۳۸۹، ساعت ۰۱:۰۶

agha salam.n tamrin forie jane man ye karish konid

کلاسي به نام integerset ايجاد کنيد. هر شيء از اين کلاس مي تواند اعدادي صحيح در بازه 0 تا 100 را بپذيرد. مجموعه به صورت آرايه اي از صفرها و يک ها نشان داده مي شود. اگر عدد صحيح i در مجموعه باشد، a[i] برابر با يک است. عنصر a[j] در صورتي صفر است که j در مجموعه نباشد.

{1,3,5,6}=[0,1,0,1,0,1,1]

سازنده مجموعه را طوري مقدار اوليه مي دهد که تمام عناصر آرايه صفر باشد.

عملگر + را به گونه اي تعريف کنيد که اجتماع دو مجموعه را حساب کند.

عملگر – را به گونه اي تعريف کنيد که اشتراک دو مجموعه را حساب کند.

عملگر == را به گونه اي تعريف کنيد که مشخص کند آيا دو مجموعه با هم برابرند؟

عملگر – را به گونه اي تعريف کنيد که مکمل يک مجموعه را حساب کند.

توابع عملگر را يک بار به عنوان اعضاي کلاس و بار ديگر، به عنوان توابع دوست تعريف  نماييد.

در دو برنامه مجزا کلاس خود را تست نماييد.

• parisa
۵ دی ۱۳۸۹، ساعت ۲۰:۲۲

salam bebakhshid mishe barnameye in soalo vasam mail konid kheyli hayatiye

کلاسي به نام integerset ايجاد کنيد. هر شيء از اين کلاس مي تواند اعدادي صحيح در بازه 0 تا 100 را بپذيرد. مجموعه به صورت آرايه اي از صفرها و يک ها نشان داده مي شود. اگر عدد صحيح i در مجموعه باشد، a[i] برابر با يک است. عنصر a[j] در صورتي صفر است که j در مجموعه نباشد.

{1,3,5,6}=[0,1,0,1,0,1,1]

سازنده مجموعه را طوري مقدار اوليه مي دهد که تمام عناصر آرايه صفر باشد.

عملگر + را به گونه اي تعريف کنيد که اجتماع دو مجموعه را حساب کند.

عملگر – را به گونه اي تعريف کنيد که اشتراک دو مجموعه را حساب کند.

عملگر == را به گونه اي تعريف کنيد که مشخص کند آيا دو مجموعه با هم برابرند؟

عملگر – را به گونه اي تعريف کنيد که مکمل يک مجموعه را حساب کند.

توابع عملگر را يک بار به عنوان اعضاي کلاس و بار ديگر، به عنوان توابع دوست تعريف  نماييد.

در دو برنامه مجزا کلاس خود را تست نماييد.

• نسترن
۷ اسفند ۱۳۹۰، ساعت ۲۰:۰۲

مرسی از توضیحات خوبتون میشه سربارگذاری رو واسه عملگر های > و < و == و != و >= و =< توضیح بدین لطفا؟؟؟ خییییلی فوریه!!

• soheil
۲۱ آذر ۱۳۹۱، ساعت ۰۲:۳۶

آقا خداوکیلی عجب سایتی دارید.یه عمره دنبال یه سایت مثل شما میگردم.خداییش خیلی عالیه

با تشکر

Soheil

www.1ke.ir

• sanaz
۱۱ خرداد ۱۳۹۲، ساعت ۱۰:۳۹

kheili kheili ali boooooooood:)

• مجید
۱۸ آبان ۱۳۹۲، ساعت ۱۲:۴۶

سلام و خسته نباشید.

من برای تعریف یک آرایه از اعداد مختلط توی c++ به کمک احتیاج دارم.لطفا راهنماییم کنین . ممنون .

• زهرا
۲۶ اردیبهشت ۱۳۹۳، ساعت ۲۲:۰۵

سلام ببخشید میشه جواب این تمرینو برام ایمیل کنید خیلی فوریه و حیاطی برای فردا لازمش دارم یه دنیا ممنون!

-----------------------------------------------------

کلاسي به نام integerset ايجاد کنيد. هر شيء از اين کلاس مي تواند اعدادي صحيح در بازه 0 تا 100 را بپذيرد. مجموعه به صورت آرايه اي از صفرها و يک ها نشان داده مي شود. اگر عدد صحيح i در مجموعه باشد، a[i] برابر با يک است. عنصر a[j] در صورتي صفر است که j در مجموعه نباشد.

{1,3,5,6}=[0,1,0,1,0,1,1]

سازنده مجموعه را طوري مقدار اوليه مي دهد که تمام عناصر آرايه صفر باشد.

عملگر + را به گونه اي تعريف کنيد که اجتماع دو مجموعه را حساب کند.

عملگر – را به گونه اي تعريف کنيد که اشتراک دو مجموعه را حساب کند.

عملگر == را به گونه اي تعريف کنيد که مشخص کند آيا دو مجموعه با هم برابرند؟

عملگر – را به گونه اي تعريف کنيد که مکمل يک مجموعه را حساب کند.

توابع عملگر را يک بار به عنوان اعضاي کلاس و بار ديگر، به عنوان توابع دوست تعريف  نماييد.

در دو برنامه مجزا کلاس خود را تست نماييد.

• AK47dev
۳۰ خرداد ۱۳۹۵، ساعت ۲۳:۲۷

من نمیدونم چرا انقد سایتتون خوبه 10

ارث بری رو هم فقط اضافه کنید

کارتون بیسته

ممنون

یا علی 060606

• محمد
۲۱ آذر ۱۳۹۵، ساعت ۱۴:۴۷

ممنون از اطلاعات عالیتون خیلی بدردم خورد06

• Sepid
۱۱ دی ۱۳۹۶، ساعت ۲۳:۴۳

دمتون گرم عالي بود، فقط كاش عملگراي ديگه روهم ميذاشتين

• ح
۱۱ مهر ۱۳۹۷، ساعت ۲۳:۵۲

مرسی

• null
۲۹ آذر ۱۳۹۷، ساعت ۲۲:۰۸

آموزشت واقعا افتضاحه هیچیمتوجه نشدم 0210

• fatemeh
۱۵ اسفند ۱۳۹۷، ساعت ۱۱:۴۲

سلام .خسته نباشید .

خواهش میکنم

الگوریتم ضرب دو عدد مختلط رو بگید بهم ضروریه

مثلا

a+ib  *  c+id

که متغییر های a.b.c.d. را ار ورودی بگیرد

در این کار حداقل از 3 ضرب استفاده شود

ممنون میشم کمکم کنید

• مبتدی
۱۸ خرداد ۱۳۹۸، ساعت ۱۳:۱۰

۱)برنامه ایی که یک کلاس از دانشجو تعریف شده باید نشان بدم عملگر بزرگ تر معدل ۲ دانشجو را با هم مقایسه میکند

۲)برنامه ای بنویسید که یک کلاس از student تعریف کنه سپس مقادیر در دانشجو را گرفته و ذخیره کنه سپس دانشجو با بیشترین معدل را چاپ کند

سلام میشه این دوتا مسعله رو حل کنید

همه جا صبحبت از + هست :((((