بستن پنجره
فرادرس - مجموعه آموزش‌های ویدئویی  مهندسی کامپیوتر - طراحی الگوریتم - ساختمان داده
بستن پنجره     از آخرین نوشته‌ها

»    مسابقه‌ی برنامه‌نویسی آنلاین Educational Codeforces Round 20

»    مسأله‌ی Encrypted SMS

»    ویدئوهای آموزشی کلاس Programming Challenges  

بستن پنجره
وبگاه
این صفحه
اشتراک‌گذاری در LinkedIn     Cloob     اشتراک‌گذاری در Twitter
اشتراک‌گذاری در Facebook     ارسال با Telegram     Google Plus
بستن پنجره
وبگاه     این صفحه
اشتراک‌گذاری در LinkedIn     Cloob     اشتراک‌گذاری در Twitter     اشتراک‌گذاری در Facebook     ارسال با Telegram     Google Plus
توابع دوست کلاس در ++C - الگوریتمستان
الگوریتمستان
2213.555.00
  »  

       

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

http://www.aachp.ir آنچه می‌خوانید ویراست جدید نوشته‌ای است که اولین بار با عنوان «توابع دوست کلاس» بهمن ماه 1385 از طریق وبگاه برنامه‌نویسی و طراحی الگوریتم (عنوان و طرح پیشین وبگاه الگوریتمستان) منتشر شده بود.


آنچه در این نوشته می‌خوانید:

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

    به زبان ساده، توابع دوست یک کلاس توابعی هستند که عضو کلاس نیستند، اما به تمامی داده‌ها و توابع خصوصی و محافظت شده‌ی آن دسترسی دارند.

یک مثال ساده

  [بازگشت به فهرست]

  

class myclass {
    friend void print_a(myclass);
  private:
    unsigned a;
  public:
    myclass(int r) {
      a = r > 0 ? r : - r;
    }
    void print() {
10       cout << a;
11     }
12 };
13   
14 void print_a(myclass ob) {
15   cout << ob.a;
16 }
17 
18 void main() {
19   myclass ob(9);
20   ob.print();
21   cout << "\t";
22   print_a(ob);
23 }

  

    خروجی به این صورت است:

      

9    9

      

    تابع دوست print_a  علیرغم اینکه عضو کلاس myclass  نیست، اما به عضو خصوصی a  از کلاس دسترسی دارد.

    این قطعه برنامه روش استفاده از توابع دوست را نشان می‌دهد. توابع دوست با کلمه‌ی کلیدی friend  در ابتدای تعریفشان مشخص می‌شوند. توجه داشته باشید که چون این توابع عضو کلاس نیستند نباید عملگر تعیین حوزه (::) زمان تعریف بلوک بدنه‌ی آنها استفاده شود. یعنی این عبارت نادرست است:

      

void myclass::print_a(myclass ob)

      

    چرا که ممکن است یک تابع، تابع دوست برای چندین کلاس مختلف باشد. درضمن بلوک بدنه این توابع باید بیرون از تعاریف هر کلاسی نوشته شوند.

    اما چرا به توابع دوست نیاز داریم؟ چه کاربردهایی دارند که علیرغم نقض آشکار قوانین شیءگرایی از آنها استفاده می‌شود؟

      

سربارگذاری عملگرها با توابع دوست

  [بازگشت به فهرست]

قبلا در مورد سربازگذاری عملگرها در زبان ++C  مطلبی ارائه شده است. در این مطلب تاکید شده بود که برای عملگرهای دودویی (مثل جمع و ضرب و ...) شیء سمت چپ، تابع عملگر مربوطه را فراخوانی می‌کند و شی سمت راست به عنوان آرگومان به تابع ارسال می‌شود. به عنوان مثال اگر عملگر + برای کلاسی سربارگذاری شده باشد، دو عبارت زیر معادل هم هستند:

      

ob1 + ob2    ≡    ob1.operator+(ob2)

      

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

      

comp operator + (double f)

      

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

    اینجاست که تابع دوست به کمک ما می‌آید. به تعریف زیر دقت کنید:

      

friend comp operator + (double f , comp c)

      

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

      

c2 = 3.5 + c1;

      

    کد کامل این کلاس به این صورت خواهد بود:

      

class comp {
    friend comp operator + (double, comp);
  private:
    double real, imag;
  public:
    comp(double r, double i) {
      real = r;
      imag = i;
    }
10     comp operator + (comp r) {
11       comp temp(real + r.real, imag + r.imag);
12       return temp;
13     }
14     comp operator + (double r)< {/P>
15       comp temp(real + r, imag);
16       return temp;
17     }
18 };
19   
20 comp operator + (double l, comp r) {
21   comp temp(l + r.real, r.imag);
22   return temp;
23 }

      

    تذکر: این تعریف برای کلاس اعداد مختلط به هیچ وجه کامل نیست و تنها قسمت کوچکی از آن را شامل می‌شود. البته کتابخانه‌های زبان ++C  هم برای کار با اعداد مختلط توابع و کلاس‌هایی دارند که همه‌ی نیازها را برآورده می‌کنند.

    نکته‌ی مهم: برای سربارگذاری عملگرهای جریان (یعنی >> و <<) چاره‌ای ندارید جز این که از توابع دوست استفاده کنید (چرا؟).


این نوشته آخرین بار در تاریخ جمعه، ۱۵ مرداد ماه ۱۳۹۵ مورد بازنویسی نگارشی قرار گرفته است.
نوشته‌های مرتبط
فرادرس - مجموعه آموزش‌های ویدئویی  مهندسی کامپیوتر - طراحی الگوریتم - ساختمان داده
        معرفی انواع ظرف‌ها (نگهدارنده‌ها - containers)  در زبان برنامه‌نویسی ++C
        آشنایی با مفهوم سربارگذاری عملگرها در زبان ++C
        معرفی فایل سرآیند algorithm  از کتابخانه قالب استاندارد زبان برنامه‌نویسی ++C  به همراه نمونه کد
        معرفی متغیرهای مرجع در زبان برنامه‌نویسی ++C  و آشنایی با مهمترین کاربردهای آنها
        آشنایی با کلاس‌های حافظه و کاربرد آنها در زبان ++C
        آموزش استفاده از آرایه‌ی پویای دو بعدی در زبان ++C
        آشنایی با حلقه‌های تکرار در زبان برنامه‌نویسی ++C  و دستورات کنترلی مورد استفاده در آن
        آشنایی با مفهوم و عملکرد اشاره‌گرها در زبان برنامه‌نویسی ++C  و ارائه مثالهایی از کاربرد آن
        پنج نکته‌ی آموزنده در مورد برنامه‌نویسی به زبان برنامه‌نویسی ++C
        آشنایی با قالب‌ها به عنوان یکی از امکانات متمایز ++C  از C
پیوند کوتاه صفحه دسته‌بندی
امتیاز نوشته
  • 1
  • 2
  • 3
  • 4
  • 5
ارسال پیام

نام: *  

پست الکترونیک:

وبگاه:

متن پیام: *

right 01 02 03 04 05 06 07 08 09 10 11 12 13 14 left

 


» F

چهارشنبه، ۲۵ اسفند ماه ۱۳۹۵، ساعت ۱۱:۲۰
سلام ببخشید من دنبال تمام توابع مربوط ب رشته هاباتوضیح ومثال میگردم البته به جز Size وLength... ممنون


جمعه، ۲۷ اسفند ماه ۱۳۹۵، ساعت ۱۴:۵۶
مسعود:
سلام
به زودی در این مورد هم نوشته‌ای اضافه می‌شه.

» سیاوش

جمعه، ۲۴ آبان ماه ۱۳۹۲، ساعت ۱۹:۵۸
با سلام و خسته نباشید


کد سورسی در c++  می خواستم که تعداد روز بین دو تاریخ شمسی رو حساب کنه و سال کبیسه و تعداد روزهای بعضی ماه ها (30 و31 روزه بودن) رو مشخص کنه .

اگه میشه پاسخ بدید چون استادمون درس نمیده و میاد سر کلاس و میگه فلان برنامه رو بنویسید و ما هم خوب یاد نمی گیریم .

خدا اجرتون بده
06

» mohmmad

یکشنبه، ۱ بهمن ماه ۱۳۹۱، ساعت ۲۱:۳۴
0202020202020202
کمک کمک کمک
چطوری میتونم درج در جریان را با استفاده از تابع عضو سربارگذاری کنم.

» موسی

پنجشنبه، ۱۹ مرداد ماه ۱۳۹۱، ساعت ۱۸:۳۴
جواب سوالی که فرستادیم رو از کجا باید  پیدا کنیم.


پنجشنبه، ۱۹ مرداد ماه ۱۳۹۱، ساعت ۲۱:۳۲
مسعود:
سوالی پرسیده نشده که جواب داده بشه. به نظر درخواست برنامه می‌یاد که اگه قسمت بالای بخش ارسال پیام رو مطالعه کرده باشید، چنین درخواستی جواب نداره.

» لطفی

پنجشنبه، ۱۹ مرداد ماه ۱۳۹۱، ساعت ۱۸:۲۳
سلام،اگه لطف جواب س<ال منو بدید ممنون میشم.
ازطریق برنامه سی++ وکلاس دوست(friend)
برنامه ای بنویسید که تاریخ تولد شخصی را با تاریخ امروز مقایسه کند اگر امروز تولدش بود پیام تبریک چاپ کند.
ممنونم.

» مهدی

یکشنبه، ۱ مرداد ماه ۱۳۹۱، ساعت ۱۱:۵۳
070707070707
جرا من هرچی کتاب میخونم ++c  رو یاد نمیگیرم/
070707070707
آخه چرا

» مسعود

پنجشنبه، ۱۱ خرداد ماه ۱۳۹۱، ساعت ۱۵:۰۷
<span style= "color: #FF5555 ">زهرا خانم چه کمکی از دست من بر می‌یاد؟</span>

» زهرا

سه‌شنبه، ۹ خرداد ماه ۱۳۹۱، ساعت ۱۲:۴۰
البته فقط به زبان c++  
خط اول سوال :کلمه درست( سلسله مراتب ) است

» زهرا

سه‌شنبه، ۹ خرداد ماه ۱۳۹۱، ساعت ۱۲:۳۴
با سلام من دانشجوی کارشناسی کامپیوتر هستم اگر می توانید در حل  ونوشتن این برنامه به من کمک کنید
اشیا زیر را در نظر بگیرید ستسته مراتبی از کلاسها را برای انها به همراه مجموعه مناسبی از توابع با وراثتی برای محاسبه حجم سطح و محیط (به شکل مناسب) توسعه دهید:جعبه - دایره- مربع- مثلث- چند ضلعی-خط- نقطه- شئ-چهار ضلعی - کره -مربع و چهار ضلعی - متواضی الاظلاع- شش ضلعی - پنج ضلعی - چهار ضلعی -
با تشکر

» alireza

دوشنبه، ۲۹ شهریور ماه ۱۳۸۹، ساعت ۱۲:۰۹
سلام دوست عزیز
امیدوارم که در کمال صحت و سلامتی باشی
آق من تو یه شرکت کار میکنم که قسمت عمدهکارش برنامه سازی هست
اما من تو فیلد سخت افزار و راه اندازی سیستم های تولیدی کار میکنم
خیلی  دوست دارم تو فیلد سی پلاس پلاس  وارد بشم
اما  نشده
می خوام کمکم کنی و جزوه خوب و روان و قدم به قذم اگه داری بهم بدی
ذوستان همکار کتاب مرجع لاتین  زیاد دادن اما اینها سنگین هست و به درد آدم مبتدی نمی خوره
ممنون

» نجمه

شنبه، ۲۲ خرداد ماه ۱۳۸۹، ساعت ۱۲:۰۷
باسلام
ميشه در سايتتون در مورد توابع عضو استاتيك مطالبي را بيان كنيد.اگر مطالب جنبه كنكوري داشته باشند بهتر است.ممنون

» مرتضی

سه‌شنبه، ۱۰ آذر ماه ۱۳۸۸، ساعت ۱۸:۴۷
باسلام.
ضمن تبریک به داشتن چنین وب سایت عالی و پرباری.....
یه سوال دارم:

من دارم یه برنامه مینویسم که شبیه برنامه های نوشته شده با ویژوال هستش، تو این برنامه کلاس های خیلی زیادی نوشتم، حالا میخوام یه کلاس convert  بنویسم که همه کلاس ها بتونن بدون ساختن یک شئ ازاون،بتونن ازش استفاده کنن.یعنی هر کلاس جدیدی هم که تعریف میکنم،بتونه بدون ساختن شئی از اون ازش استفاده کنه.چون میخوام این کلاس بین همه کلاس ها مشترک باشه.چطور؟؟
راستی من اصلا برنامه نویسی استاتیک بلد نیستم.


ممنوووون.


سه‌شنبه، ۱۰ آذر ماه ۱۳۸۸، ساعت ۲۰:۰۶
مسعود:
سلام
ممنون از لطفت.
شما می خوای با ++C  برنامه بنویسی؟ یعنی می خوای همه کلاسهایی که داری بتونن از محتویات این کلاس به صورت مستقیم استفاده کنن؟