تکین وب | آموزش برنامه نویسی
تکین وب | آموزش برنامه نویسی

توابع و کلاس های دوست در ++C

۵ بهمن ۱۳۹۴

می توان در شیء گرایی ++C  از قابلیت کلاس ها و توابع دوست استفاده کرد . به این معنا که می توان به توابع و یا اعضای یک کلاس دسترسی داشت :

توابع دوست

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

در ++C  گاهی در طراحی کلاسهای متفاوت ممکن است لازم باشد از طریق یک دستگیره( Handle ) مقدار یک عضو از یک کلاس تغییر پیدا کند . اما این تغییر به معنای این نیست که عضو حالت public پیدا کند و در جاهای دیگر مثلا در main از آن بتوان استفاده کرد . بلکه ++C اجازه ی دسترسی به اعضای یک کلاس را از طریق کلمه کلیدی friend به ما می دهد :

#ifndef COUNT_H
#define COUNT_H
#include<iostream>
using namespace std;
class count
{
friend void set_x(count &l , int y);//اعلان تابع دوست 
private:
	int x ;
public :
	count():x(0)
	{
	}
	void print() const
	{
		cout<<x<<endl;
	}

};
#endif

کد بالا یک کلاس ساده با یک عضو خصوصی و تابع عضو ثابت را نشان می دهد . اما همانطور که مشاهده می کنید تابع set_x در این کلاس به عنوان تابع دوست با استفاده از کلمه کلیدی friend به کار برده شده است :

friend void set_x(count &l , int y);//اعلان تابع دوست

اگر به یاد داشته باشید ، گفتیم در یک کلاس اگر از کلمه ی private استفاده نشود ، آن عضو به عنوان یک عضو خصوصی در نظر گرفته می شود . بنابراین در اینجا نیز تابع دوست به عنوان یک عضو خصوصی درنظر گرفته شده است . اما فرقی نمی کند که آن را در سطح private یا در سطح public تعریف کنیم . ( میتوانید برای امتحان ، خودتان همین برنامه را با قرار دادن تابع دوست در قسمت public  اجرا کنید . )

تعریف این تابع مانند توابع معمولی که خارج از main تعریف میکردیم بدون علامت :: ، تعریف خواهد شد :

#include"iostream"
#include<stdlib.h>
#include"count.h"
using namespace std;
void set_x(count &c , int y);
int main()
{
	count c1;
	cout<<"x before call set_x : ";
	c1.print();
	set_x(c1 , 4);
	cout<<"x after call set_x : ";
	c1.print();
	system("pause");
}
//define function
void set_x(count &l , int y)
{
	l.x = y;

}

دقت کنید اگر از کلمه ی friend استفاده نکنید ، یک خطاست .

تابع set_x دارای دو پارامتر ورودی می باشد ، که یکی از آنها از نوع int و دیگری از نوع کلاس count می باشد . با استفاده از پارامتری که از نوع کلاس count تعریف کرده ایم می توانیم از آن به عنوان یک Handle یا دستگیره به عضو خصوصی کلاسمان دسترسی داشته باشیم .

دسترسی به عضو کلاس به وسیله نقطه یا دات صورت می گیرد .

با اجرای این برنامه به خوبی می توانید متوجه این دسترسی از طریق یک تابع خارج از کلاس شوید .

کلاس های دوست

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

class A
{
   friend class B;
   private:
   ....
   public:
   ....
};

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

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

برای درک موضوع به بررسی مثال زیر می پردازیم :

#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle {
    int width, height;
  public:
    Rectangle() {}
    Rectangle (int &x, int &y) : width(x), height(y) 
	{
		//empty body
	}
    int area() {return width * height;}
	void convert (Square &a) 
		{
		 width = a.side;
		 height = a.side;
		}
};
#endif

در این کد کلاس rectangle یا مستطیل پیاده سازی شده است که دو سازنده دارد . اولین سازنده هیچ پارامتر ورودی ای ندارد و دومین سازنده دو پارامتر ورودی از نوع صحیح دریافت می کند . تابع ()area دو پارامتری را که سازنده از main دریافت می کند را درهم ضرب کرده و به عنوان خروجی برمیگراند .

تابع convert پارامتری از نوع کلاس square دریافت می کند و چون کلاس squareدوست کلاس rectangle می باشد ، بنابراین کلاس rectangle می تواند به اعضای خصوصی کلاس square دسترسی داشته باشد و این دسترسی به وسیله ی یک handle یا دستگیره ( یعنی همان پارامتر ورودی تابع convert) صورت می گیرد :

#include"iostream"
using namespace std;
#ifndef SQUARE_H
#define SQUARE_H
class Square {
  friend class Rectangle;
  private:
    int side;
  public:
    Square (int a) : side(a) 
	{
		//empty body
	}
};
#endif

در اینصورت main برنامه را به صورت زیر تعریف میکنیم :

#include"iostream"
#include"rectangle.h"
#include"square.h"
#include<stdlib.h>
using std::cout;
using std::endl;
int main () 
{
  Rectangle rect;
  Square sqr (4);
  rect.convert(sqr);
  cout << rect.area()<<endl;
  system("pause");
  return 0;
}

در این قسمت ابتدا یک شیء از کلاس Rectangle ساخته می شود . سپس با ساخت شیءای از کلاس Square با پارامتر ورودی ۴ ، سازنده ی این کلاس فراخوانی می شود . عدد ۴ به عنوان مقدار اولیه عضو خصوصی کلاس ،  یعنی side قرار داده می شود . سپس کنترل برنامه از کلاس square به داخل main برمی گردد و به وسیله ی شیء ای که از کلاس rectangle ساخته بودیم ، تابع عضو کلاس rectangle یعنی convert فراخوانی می شود و به عنوان ورودی شیءای از کلاس square به این تابع فرستاده می شود . کنترل برنامه به داخل کلاس rectangle می رود و چون رابطه ی دوستی بین این دو کلاس برقرار است ، از طریق مقداری که عضو خصوصی کلاس square دریافت کرده است (یعنی عدد ۴) ، اعضای خصوصی کلاس rectangle مقداردهی می شوند . در اینصورت با فراخوانی تابع area ضرب ۴ در خودش یعنی ۱۶ به عنوان خروجی نمایش داده خواهد شد .(توجه کنید که از سازنده ی دومی که برای کلاس rectangle تعریف کرده بودیم ، استفاده نشده است .)

یکی از بهترین و پرکاربردترین مثالهای کلاس های دوست ، کلاس لیست پیوندی می باشد که در بخش های بعدی به پیاده سازی کامل آن خواهیم پرداخت ….

در ضمن اگر اینستاگرامی هستید حتما @Takinweb را فالو کنید….


    

درباره ی عطیه رحمانی

دیدگاه ها

نظرات بسته شده است.

کلیه ی حقوق مادی و معنوی مطالب متعلق به سایت تکین وب می باشد و کپی برداری و بازنشر آن بدون ذکر منبع کاری غیر حرفه ای و غیر اخلاقی و قابل پیگرد قانونی خواهد بود.
کانال تلگرام تکین وب