وبلاگ من

۳ مطلب در تیر ۱۳۹۶ ثبت شده است

سر بارگذاری عملگر ها

دوشنبه, ۱۲ تیر ۱۳۹۶، ۰۵:۵۱ ب.ظ

عبارت A = B + C را در نظر بگیرید به A,B,C عملوند و به +,= عملگر می گویند . در c++ می توان نحوه کار هر عملگر را تعیین کرد.


 درواقع وقتی می نویسید A+B تابعی مانند

 A.operator +(B);

در برنامه فراخوانی می شود .

همانطور که مشخص است عملگر + (operator +)  یک تابع از شی A است که تنها یک ورودی می گیرد . این ورودی می تواند از جنس A (یعنی A و B هر دو از جنس یک کلاس هستند ) باشند یا حتی از یک جنس نباشند مثلا A از جنس کلاسی مانند test و B عددی int باشد.


برای مثال کلاس test را در نظر بگیرید . در تعریف این کلاس تنها یک عدد صحیح int x وجود دارد می خواهیم عملگر های + و >> را برای آن بنویسیم:

#include "stdafx.h"
#include <iostream>
using namespace std;
class test
{
int x; //varible
public:
test operator + (test temp); 
friend ostream& operator << (ostream &out, test temp);
test(int a) { x = a; } //contractor
};
// + operator overloading
test test::operator +(test temp)
{
x += temp.x;
return *this;
}
// << operator overloading
ostream& operator << (ostream &out, test temp)
{
cout << temp.x;
return out;
}
int _tmain(int argc, _TCHAR* argv[])
{
test A(2);
test B(3);

cout << A + B;
system("pause");
return 0;
}

همان طور که گفتیم هر عملگر در واقع تابعی از کلاسی است که تعریف می کنیم . از طرفی هر تابع  باید یک نوع خروجی داشته باشد void , int , ... یا از نوع خود کلاس . وقتی می نویسیم A+B در واقع آن را برابر یک متغییر دیگر می کنیم در این جا از نوع کلاس . اگر خروجی از نوع int باشد هم مشکلی برای جمع دو متغییر پیش نمی آید اما اگر داشته باشیم A + B + C در این صورت دو متغییر اول جمع شده به صورت int در می آیند سپس با عبارتی مثل int X + C رو به رو می شویم که در تعریف عملگر وجود ندارد پس برای رفع این مشکل نوع خروجی را از نوع کلاس تعیین می کنیم. 


عملگر >> عضوی از کلاس test نیست چون عبارتی مثل cout<<A همان:

operator << (cout , A);

 همان طور که مشخص است این تابع(همان عملگر >>) وابته به کلاس نیست و تنها باید به محتویات آن  دسترسی داشته باشد پس به صورت  دوست برای کلاس تعریف می شود

 & اول برای این است که خروجی تابع به صورت ارجاعی باشد که در ادامه علت آن را توضیح می دهیم . تابع دو نوع ورودی دارد اول از جنس ostream است (cout نوعی جریان خروجی برای نمایش اطلاعات روی مانیتور است که از جنس کلاس ostream می باشد از دیگر جریان های خروجی ofstream است که هنگام کار با فایل از ان استفاده می کردیم )  و دومی از نوع کلاس ... در  out& علامت & برای out ارسال به صورت ارجاع و نه کپی است .

تابع آدرس out را در پایان برمی گرداند (ارجاع به ostream&  ... برای برگرداندن آدرس نیازی نیست *out بنویسم این مفهوم برای اشاره گر است و برای ارسال آدرس نیازی نیست حتما از اشاره گر استفاده کنیم)

( اگر خروجی تابع از نوع void می شد برای cout <<A مشکلی وجود نداشت اما برای cout<<A<<B مثل int و  نوع کلاس همان مشکل پیش می آید پس خروجی باید ostream باشد )

  • مرتضی رحیم زاده

توابع و کلاس های دوست

دوشنبه, ۱۲ تیر ۱۳۹۶، ۱۱:۳۰ ق.ظ

برای اینکه به یک تابع یا کلاس (مثلا تابع B) اجازه دهیم که به مقادیر کلاس (مثلا  A) دسترسی پیدا کند . باید برای کلاس A تعریف کنیم که تابع یا کلاس B را به عنوان دوست در نظر بگیر برای این کار از کلمه کلیدی friend در بدنه کلاس A به همراه امضای تابع B استفاده می کنیم :

class A
{
friend void B();
};
void B() {}

برای مثال کلاسی به نام test را در نظر بگیرد ... تابع show برای این کلاس را به صورت دوست تعریف می کنیم:

#include <iostream>
using namespace std;
class test
{
int x,y;
friend void show(test);
public:
test(int a,int b) //contractor
{
x=a;
y=b;
}
};
void show(test T) 
{
cout<<T.x<<T.y<<endl;
}

int main(int argc, char** argv) {

test A(2,3);
show(A);

test B(8,9);
show(B);

return 0;
}


و برای دو کلاس به عنوان دوست :

کلاس B به عنوان دوست برای کلاس A تعریف شده است یعنی می تواند به متغییر ها و توابع خصوصی و محافظت شده ی آن دسترسی داشته باشد . ان دسترسی از طریق شی از A امکان پذیر است مثلا در این مثال ما به کمک شی a از نوع کلاس A در تابع set کلاس B مقادیر x و y را تغییر می دهیم.


#include "stdafx.h"
#include <iostream>
using namespace std;
class A
{
friend class B;
private:
int x;
protected:
int y;
public:
A(){ x = 0; y = 0; } //contractor
};
class B
{
public:
void set(A a)
{
a.x = 2;
a.y = 2;
}
};



int _tmain(int argc, _TCHAR* argv[])
{
B Mb;
A Ma;
Mb.set(Ma);
return 0;
}


  • مرتضی رحیم زاده

تعریف متغییر static در یک کلاس

دوشنبه, ۱۲ تیر ۱۳۹۶، ۱۱:۱۲ ق.ظ

شکل کلی تعریف یک متغییر استاتیک در کلاس به این صورت است:

class test
{
static int x;
};
int test::x=0; 

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


برای مثال اگر بخواهیم تعداد متغییر ها ی تعریف شده از کلاس test را داشته باشیم باید یک متغییر int از نوع static تعریف کرده ، هر بار در تابع سازنده (جایی که یک شی از کلاس هنگام تعریف در آنجا مقدار دهی می شود) رفته و به مقدار x یکی اضافه کنیم :

#include <iostream>
using namespace std;
class test
{
public:
test() //contractor
{
x++;
cout<<x<<endl;
}

static int x;

void PrintX() {cout<<x<<endl;}
};
int test::x=0; 
int main(int argc, char** argv) {

test A,B;

return 0;
}



  • مرتضی رحیم زاده