دسترسی مهمان ها محدود است، برای استفاده از انجمن وارد شوید، اگر حساب کاربری ندارید ابتدا ثبت نام کنید و سپس وارد شوید.

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

مهمان گرامی، هرگونه ارسال پست نامرتبط به نام و محور موضوع انجمن از این لحظه ممنوع بوده و مشاهده آن نیز محرومیت در پی خواهد داشت.


امتیاز موضوع:
  • 1 رأی - میانگین امتیازات: 5
  • 1
  • 2
  • 3
  • 4
  • 5
خلاصه مباحث شی گرایی
#1
با سلام خدمت دوستان محترم.فصول آخر کتاب مربوط به کلاس و یا همون شی گرایی هستش که گستردگی زیادی داره.
مخصوصا از روی کتاب خواندنش که دیگه هیچی.چون یه 100 صفحه ای میشه.
خواستم با کمک هم این مبحث هارو پیش ببریم و درک کنیم.

دوستانی که میتونن مارو همراهی کنن.چون فردا امتحانه و تایممون کم.


از پست بعدی شروع میکنیم.
به دنیای من خوش اومدی...
هیــــــــــچ چیــــــز بـــــــی دلیــــل نیستــــــ
پاسخ
 سپاس شده توسطsMostafaB (4-2-1393، 11:19 صبح)
#2
کلاس چیست؟
کلاس یه سری کارهایی هست که مخصوص متغیر های کلاس هست.مثلا یه تابع ساختیم به اسم cube که توان 3 یک عدد رو بدست میاره.اما ما میخوایم فقط این خاصیت و این تابع برای متغیر های خاصی باشه.برای همین از کلاس استفاده میکنیم.
کلاس غیر از این باعث میشه که این خاصیت های یکسان رو به چند عنصر بدیم.و این خیلی کار برنامه نویس رو راحت تر و سریع تر میکنه.حجم کد هم کاهش چشم گیری میده.
بدنه یا چارت اصلی اعلان (تعریف) کلاس به شکل زیر و بالای بدنه اصلی برنامه هستش.

کد:
class name
{.
.
.
.
};

جای نقطه چین ها صفت ها و متد ها (همان متغیر ها و توابع) و همینطور در صورت خواستن سازنده و نابود گر و... هستش.

*استاد سمیکالن آخر کلاس رو نمیذاشت.شما هم حال نداشتید نذارید.D


برای درک بهتر کلاس ، مثل آرایه ها بهتر هست که شکلی براش بکشیم.
شکل کلیش به این صورت هستش:







روی عکس توضیحات مربوط بهش داده شده.
حالا میخوایم با هم یک کلاس ساده بسازیم که دارای دو متغیر a و b هست و یک متد یا همون تابع که حاصل جمع a و b رو نمایش میده:

اولین کاری که میکنیم اینه که شکلش رو میکشیم.





خب دقت کردید که تو قسمت بالایی که مربوط به متغیر ها بود، متغیر هامون رو تعریف کردیم.قسمت توابع تابعی که لازم داشتیم و قسمت سازنده چیزی ننوشتیم چون لازمش نداشتیم.حالا کد رو با توجه به شکل بنویسید:

کد:
class sum
{
int a;
int b;
void sum()
   {
   cout << a+b;
   }
};

به همین سادگی.انگار یه یه برنامه نوشتید و تابع.چیز اضافه ای توش نبود.اسم کلاس هم سام گذاشتیم.حالا این کلاس ما بود.میخوایم یه نمونه توی برنامه بکار بگیریم که ببینیم چجوریه؛ کد کاملش میشه:

کد:
class sum
{
int a;
int b;
void sum()
   {
   cout << a+b;
   }
};

void main()
{
sum my;
my.a = 2;
my.b = 7;
my.sum();
}


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

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


نکته آخر: درنهایت اینکه ما شکل کلاس کلی رو کشیدیم.حالا وقتی یدونه شی از اون کلاس میسازیم دوباره شکلشو میکشیم و اسم اون شی رو بهش میدیم.به شکل زیر میشه:



شاید بخواید دلیلشو بدونید، باشه منم میگم دلیلشو.اینکار برای اینه که اگر خواستید روی دوتا شی یا صفت های دو شیء و یا چندتا راحت تر بتونید انجام بدید و اطمینان خاطر بیشتر داشته باشید.Blush


* پس فرقی نداشت که کلاس چجوری باشه.متغیر و تابع و هرچیزی دیگه که مثل کد تعریف میکنیم توی شکلش هم همونطور کدشو مینویسیم.Heart
به دنیای من خوش اومدی...
هیــــــــــچ چیــــــز بـــــــی دلیــــل نیستــــــ
پاسخ
 سپاس شده توسطsMostafaB (4-2-1393، 11:22 صبح) ، S_H (4-2-1393، 12:59 عصر)
#3
حالا به مباحث سازنده میپردازیم DodgyD

سازنده چیست؟
سازنده همونطور که از اسمش میاد باعث ساختن میشه.ما دیوار خونه و سقفشو زدیم اما وقتی زمین نداره آیا میشه بهش گفت خانه؟برای درک بهتر میشه گفت که من میگم a+b چند میشه؟! درصورتی که هیچ کدوم از اونا مقداری ندارن.وقتی مقدار نداشته باشن و بخوایم روشون عملیاتی انجام بدیم برنامه مسلما دچار ارور میشه.برای اینکه از ارور جلوگیری کنیم از سازنده استفاده میکنیم.
سازنده ها مثل همون تابع ها هستن.میتونن بدون ورودی باشن یا با چندتا ورودی.
فرق سازنده و تابع اینه که بدون نوع اعلام میشن بدون (int , viod و ... )
اسم سازنده (تابعی که بهش سازنده اطلاق میشه) همان اسم کلاس هست.
یه کلاس میتونه چندتا سازنده داشته باشه (تفاوت سازنده هاش توی تعداد ورودیش هست که دقیقا مثل تابع از همین نظر ، از هم تمیز داده میشن.)


توضیحات بالا بیشتر حاوی نکاتی بود که ممکنه تستی بیاد براتون.;)
حالا نحوه تعریف توی همون کلاس بالا و استفاده توی برنامه رو میبینیم.و بعد نکات رو کم کم اضافه میکنیم.
کد:
class sum
{
int a;
int b;
void sum()
   {
   cout << a+b;
   }
sum()
   {
   a=0;
   b=3;
   }

};

void main()
{
sum my;
my.b = 7;
my.sum();
}

خب بچه ها دقت کنید نحوه فراخوانی اون سازنده که بدون ورودی هست چطوره؟!
وقتی ما شیء رو میسازیم با دستور ;sum my انگار که اون سازنده فراخوانی شده و مقدار های اولیه داده شده.
حالا مقدار ;()my.sum چی هست؟ 0+7 میشه 7.
اگر بجای اینکه مقدار 7 رو توی تابع به b بدیم به a میدادیم میشد چی؟ 7+3 میشه 10.

خیلی ساده بود.Angel


حالا همونطور که گفتم یک کلاس میتونه چندتا سازنده داشته باشه.سازنده ای که میخوایم تعریف کنیم رو با یک و دو و سه مقدار ورودی برای مثال مینویسیم و برای شیء های مختلف استفادشون میکنیم.
کد:
class sum
{
int a;
int b;
void sum()
   {
   cout << a+b;
   }
sum(){a=0;b=3;}
sum(int n){a=n;b=n;}
sum(int x,int y){a=y;b=x;}
sum(int x,int y,int z){a=y;b=x-2;}
};

void main()
{
sum my,mohammad(10),ali(44,0);
sum mehdi(10,12,30);
my.b = 7;
my.sum();
mohammad.sum();
ali.a=35;
ali.sum();
mehdi.sum();
}

خب ما 4 تا سازنده داریم.
4 تا شی ساختیم که هر کدوم رو با یه سازنده متفاوت ایجاد کردیم به اسم های my و mohammad و ali و mehdi.
چیزی که برامون مهمه اینه که ببینیم خروجی سام چی هست.با توجه به کد های برنامه به ترتیب خروجی های تابع sum هر شی رو مینویسم.
7
20
79
20

به همین سادگی به همین خوشمزگی.HeartDHeart


تا اینجا با سازنده به طور کامل آشنا شدید.حالا دوتا حالت داریم که یکیش اصلی تر هست رو زودتر میگیمD


اگر که دقت کنید کار اصلی سازنده مقدار دهی اولیه و معمولا مستقیم هست.یعنی عیناً هر چی که میدیم توی متغیرمون کپی میشه « درست مثل سازنده های یک و دو ورودی مثال بالا »برای همین اومد این دستوراتو پروند و گفت میتونید بجای دستور اینطور بنویسید:
کد:
sum(int n):a(n),b(n){}
sum(int x,int y):a(y),b(x){}

پس هیچ فرقی نداره که اینطور مقدار بدیم یا اونطور.جفتشون یه کار میکنن.
اما یادتون باشه اگر میخواید روی ورودی تغییر ایجاد کنید « مثل سازنده سه ورودی مثال بالا که x-2 شده بعد به b داده شده » از این استفاده نکنید.فقط دستور...


اینم متوجه شدیدحتماHeart
AngelAngelAngelAngel



حالا حالت دومی که میخوایم بگیم...
اگر که بالای بالا دقت کرده باشید گفتم سازنده مثل یه تابع هستش.تابع ها یه خاصیت داشتن که میتونستیم توی تعریفش مقدار دهی اولیه کنیم بهش.
این یه خوبی داشت، اونم این بود که وقتی تابع ما 3 پارامتر ورودی میخواد و ما دوتا ارسال میکنیم برنامه ارور نمیده و اون مقدار پیشفرض رو برای کارش درنظر میگیره.
سازنده مقدار دهی شده پیشفرض برای کلاس ها یه خوبی دیگه هم داره.میتونیم یه سازنده تعریف کنیم با چند پارامتر و هرچقدر که خواستیم بنا به نیازمون ورودی هارو بهش بدیم.
توی کد زیر راحت تر درک میشه:
کد:
class sum
{
int a;
int b;
void sum()
   {
   cout << a+b;
   }
sum(int x=0,int y=1,int z=0){a=y+z;b=x-2;}
};

void main()
{
sum my,mohammad(10),ali(44,0);
sum mehdi(10,12,30);
my.sum();
mohammad.sum();
ali.sum();
mehdi.sum();
}


دقت کنید؛ همشون با یه سازنده تونستن مقدار دهی اولیه بشن و روشون محاسبات انجام بشه. حالا طبق کد خروجی ها هم به صورت زیر هستش به ترتیب:
-1
9
42
50





خب سازنده های اصلی تموم شدن و به همین سادگی بود.امیدوارم مفید بوده باشه.
موفق و سربلند باشید دوستانHeart
به دنیای من خوش اومدی...
هیــــــــــچ چیــــــز بـــــــی دلیــــل نیستــــــ
پاسخ
 سپاس شده توسطsMostafaB (4-2-1393، 03:37 عصر)
#4
نابود گر....Angry

رسیدیم به مبحث شیرین نابودگر.دیدید میزنید یه لامپ مهتابیو خرد میکنید چه حالی میده؟نابود کردن کلاسم همون حالو میده چون منابع استفاده شده آزاد میشه دیگه.(چه ربطی داشت خودمم نمیدونم Undecided )

نکته ای که هست اینه که نابود کننده کلاس فقط یدونه میتونه باشه
هم نام کلاس هست اما قبلش علامت ~ داره.
درنهایت هم میشه گفت که تاحالا من ندیدم متغیر ورودی داشته باشه.
میتونه توش دستوراتی هم قرار بگیره مثل سازنده
یه کد میزنیم و درکش میکنیم:

کد:
class sum
{
int a;
int b;
void jame()
  {
  cout << a+b;
  }
sum(int x=0,int y=1,int z=0){a=y+z;b=x-2;}
~sum(){}
};

void main()
{
sum my;
 {
 sum mehdi(10,12);
 mehdi.jame();
 }
my.jame();
mehdi.jame();
}


خب بچه ها.نگاه کنید به دقت.کلاس داریم به اسم sum که شیء های my و mehdi رو ساختیم.اما دقت کنید بیشتر.ما سازنده رو فراخوانی کردیم اما نابود کننده رو چطور فراخوانی کنیم؟

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

اینم ساده بود.;)
به دنیای من خوش اومدی...
هیــــــــــچ چیــــــز بـــــــی دلیــــل نیستــــــ
پاسخ
 سپاس شده توسطsMostafaB (4-2-1393، 03:51 عصر)
#5
سازنده کپی چیست؟

خب بچه ها سازنده که میدونید چیه؟چیزی که به متغیر ها مقادیر اولیه میده.اما سازنده کپی چیه! سازنده کپی همون سازندس اما مقادیر پیشفرض رو از شیء دیگه منتقل میکنه به شی جدید.
به اسمش دقت کنید>>> سازنده کپی
توی اسمش سازنده وجود داره پس از قوانین سازنده ها پیروی میکنه.پس برای ایجادش به صورت زیر استفاده میکنیم:
کد:
sum(const sum& ccopy):a(ccopy.a), b(ccopy.b){}

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


با مثال بهتر میشه درکش کرد.به کد زیر توجه بنمایید:
کد:
class sum
{
int a;
int b;
void jame()
   {
   cout << a+b;
   }
sum(int x=0,int y=0){a=x;b=y;}
sum(const sum& ccopy):a(ccopy.a), b(ccopy.b){}
~sum(){}
};

void main()
{
sum my;
sum ali(my);
my.a = 4;
my.b = 12;
sum mehdi(my);
}

خب بچه ها.کد بالا دارای سازنده، سازنده کپی ، نابودگر ، متغیر هایی هست.
بعد از اتمام برنامه شی های ایجاد شده به ترتیب به این شکل هستن:








خب بچه ها دقت کردید چه اتفاقی افتاد! مای رو تعریف کردیم و بلا فاصله از یه کپی گرفتیم دادیم به علی
حالا که ما هنوز مقداری به مای نداده بودیم مقدار سازنده پیشفرض توش بود یعنی 0 0
بعد به همین دلیل علی 0 0 شد.
بعد که به مای مقادیری دادیم مثل 10 و 7 و بعد از اینکار یه کپی گرفتیم و به مهدی فرستادیم، مهدی هم مقادیر 10 و 7 رو گرفت.


کل سازنده کپی نکتش یکی ایجادش توی کلاسه و دیگری هم این که الان گفتیم.Sleepy
به دنیای من خوش اومدی...
هیــــــــــچ چیــــــز بـــــــی دلیــــل نیستــــــ
پاسخ
 سپاس شده توسطS_H (4-2-1393، 04:28 عصر) ، sMostafaB (4-2-1393، 05:22 عصر)
#6
اشاره گر به اشیا

خب دوستان همون طور که یادتون هست برای رسیدن به قسمت مورد نظر از اشیا اون رو به این صورت مینوشتیم که « صفت یا متد.اسم شی »مثلا my.a
و همینطور یادتون هست که برای استفاده اشاره‌گر و بکارگیری اون برای فراخوانی محتوی اون متغیر از علامت ستاره قبل از اشاره‌گر استفاده میکنیم.

اما برای استفاده توی آرایه یکم مدلش فرق داشت اینطوری میشد (p+1)*
حالا برای کلاس هم یکمی فرق داره.دوتا حالت داره که میشه از جفتش استفاده کرد.
اولیش: 
کد:
(*p).data = 22;

دومیش:
کد:
p->data = 22;


استفاده از اشاره گر توی ایجاد کلاس یه خوبی دیگه هم داره.خوبیش اینه که میشه پویا ساختش و بعدا حذفش کرد و حافظه رو خالی کرد.

برای اعلانش هم دقیقا عین همون اعلان متغیر پویا هستش.به شکل زیر
کد:
sum* p = new sum;


به همین سادگی به همین زیبایی.HeartAngelHeart
به دنیای من خوش اومدی...
هیــــــــــچ چیــــــز بـــــــی دلیــــل نیستــــــ
پاسخ
 سپاس شده توسطsMostafaB (4-2-1393، 05:22 عصر)
#7
اعضای عمومی ، خصوصی و ایستا کلاس:

درودی دوباره خدمت دوستان عزیز.
تا الان درمورد نحوه ایجاد به حالت عادی و عمومی کلاس بحث شد اما ما میخوایم یکم استاندارد تر بنویسیم.
اعضای عمومی شامل: متغیر ها ، متد ها و... می باشد که با کلمه کلیدی public توی برنامه معرفی شده باشن.برای تعریف اعضای عمومی به وسیله کلمه پابلیک به صورت زیر مینویسیم:
کد:
class sum
{
public:
  int a;
  int b;
  void jame()
     {
     cout << a+b;
     }
  sum(int x=0,int y=0){a=x;b=y;}
  sum(const sum& ccopy):a(ccopy.a), b(ccopy.b){}
  ~sum(){}
};

دقت کنید که همه اعضا از نوع پابلیک یا همون عمومی پیروی میکنن.

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


حالا عضو خصوصیه نقشش چیه؟
یه سری از متغیر ها هستن که نیاز به دسترسی مستقیم کاربر برای پرکردن ندارن و یا حتی دادن دسترسی عمومی به آنها ممکن است مشکلات امنیتی و خطاهایی رو توی برنامه ایجاد کنه.برای همین از نوع خصوصی استفاده میشه تا از این خطاها جلوگیری بشه.
کلمه کلیدیش private هست.مثل بابلیک هم کارگرفته میشه.
برای مثال:
کد:
class sum
{
private:
  int a;
  int b;
public:
  void jame(int x,int y)
     {
     a=x;
     b=y;
     }
  sum(int x=0,int y=0){a=x;b=y;}
  sum(const sum& ccopy):a(ccopy.a), b(ccopy.b){}
  ~sum(){}
};

میبینید که متغیر های a و b رو خصوصی کردیم.با اینکار توی کد های برنامه اصلی اگر بنویسیم مثلا my.a و مقداری بهش بدیم به هیچ عنوان عمل نمیکنه چون اجازه دسترسی نداره.

خب سوال اینه که چطور میشه پرشون کرد پس.جواب اینه که با استفاده از همون سازنده و توابعی که به صورت عمومی قابل دسترس هستند.نمونه تابع jame که دوتا مقدار میگیره و a و b رو مقدار دهی میکنه.



*** نکته مهم:معمولا سازنده ها از نوع عمومی باید تعریف شوند.نکتش اختراعی خودمه D


*** نکته مهم:اعضای خصوصی فقط و فقط از طریق اعضای همان کلاس قابل دسترسی هستند.حتی برای ورودی و چاپ.





عضو داده‌ای ایستا:

عضو داده‌ای ایستا در اصل یک خانه(متغیر) مشترک بین تمامی شی های ایجاد شده از یک کلاس هست.مثلا a رو ایستا میگیریم، وقتی بهش مقدار 5 بدیم توی فراخوانی تمام شی ها هم همین مقدار 5 فراخوانی میشه.
این نوع مربوط به تعریف کلاس هست و با کلمه کلیدی static قبل از اعلان متغیر بکار میره.
به کد زیر دقت کنید تا نحوه اعلان رو بهتر درک کنید:
کد:
class sum
{
private:
  int a;
  int b;
public:
  static int c;


نحوه اعلان رو یاد گرفتید اما دقت کنید که عضو داده ای ایستا به هیچ عنوان توی بدنه اصلی برنامه نمیتونه مقدار دهی بشه(اینم خودم از تفکرات خودم درآوردم چون تو همه مثالاش اینطوریهD اگر میدونید اینطور نیست حتما بگید.).هرچی هست خارج و بالای بدنه اصلی برنامه آن هم با خط کد زیر:
کد:
int sum::c = 10;


***نکته مهمی که هست اینه که برای نمایش این مقدار ثابت اگر جزو اعضای عمومی باشه میشه به صورت my.c نمایشش داد.
اما اگر به صورت خصوصی باشه باید با استفاده از تابعی که عمومی هست(از بدنه اصلی برنامه بهش دسترسی میشه داشت) اون رو فراخوانی و چاپ کرد.




حالا این برای متغیر بود.ما اگر متدی رو ایستا کنیم چی میشه؟

توابع عضو ایستا:
این توابع برخلاف عضو داده ای ایستا قابلیت دسترسی از داخلی برنامه رو دارند اما به شرایط خاصی که به هیچ کدوم از اشیا مرتبط نباشه و جداگونه و مستقل فراخوانی بشه.
به کد زیر دقت کنید متوجه میشید:
کد:
class sum
{
private:
  int a;
  int b;
public:
  static int c;
  static void jame(int x,int y)
     {
     a=x;
     b=y;
     }
  sum(int x=0,int y=0){a=x;b=y;}
  sum(const sum& ccopy):a(ccopy.a), b(ccopy.b){}
  ~sum(){}
};

void main()
{
sum my;
sum::jame();
}

میبینید که متد jame به چه شکل فراخوانی شد.خارج از اینکه به شیء خاصی تعلق داشته باشه.


کدها فقط برای نمونه و مثال بودش.توجه زیادی بهشون نکنید که چکاری انجام میدن.HeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeartHeart
به دنیای من خوش اومدی...
هیــــــــــچ چیــــــز بـــــــی دلیــــل نیستــــــ
پاسخ
 سپاس شده توسطsMostafaB (4-2-1393، 07:16 عصر)


پرش به انجمن:


کاربرانِ درحال بازدید از این موضوع: 1 مهمان