View Full Version : سوال پايه اي در مورد كلاس
dr-data
شنبه 01 بهمن 1390, 22:26 عصر
سلام به همه دوستان.
من رشتم برقه و برنامه نويس تخصصي pc نيستم ولي در حد متوسط برنامه نويسي كردم مثلا، فلان ماتريس رو بگيره و يه كارايي كنه و يه خروجي توليد كنه.
يه سوال دارم در مورد كلاس در c++ !
ببينيد من كاري به دستورات و ... ندارم اونا رو بلدم و باهاشون كار كردم، تابع هم كه معلومه چيه و ازش استفاده كردم، ولي اين كلاس رو نميفهمم چيه! اون مثال ديتل ديتل رو خوندم ولي باز نفهميدم!
يه كسي ميتونه به زبان ساده بگه اين قضيه رو با ذكر يه مثال در visual studio 2008 ؟ كلاً چيه و كجا و چرا بايد استفاده شن؟
مرسي
cpppro
یک شنبه 02 بهمن 1390, 14:30 عصر
راستش کلاس بحثش گستردس.ولی اگه بخام ساده بگم شما الان دانشجوی برق هستیم.وقتی یه برنامه مثلا با سی یا سی پلاس پلاس مینویسین از بالا شروع به نوشتن کدا و یا توابع میکنین.همش رو هم پشت سر هم مینویسین.و انتظار دارین همه کدها به صورت عادی به صورت گام به گام و پشت هم اجرا بشن.
برای برنامه های ساده که کارای خیلی پیچیده ای نمیکنن این روش خوب و ساده هست و خیلی راحت هم جواب میده.
ولی فرض کنین شما بخوایین یه سیستم عامل طراحی کنین یا حتی یه برنامه مثل همین ویژوال استدیو یا فوتوشاپ یا ...
تو این حالت اگه شما بخوایین با روش بالا کدنویسی کنین تقریبا غیر ممکن هست.چون این برنامه ها حداقل دارای چندین ملیون خط کد برنامه نویسی هستن.و نوشتن اونها تو یه محیط ساده و مدیریت نشده غیر ممکن هست.
به غیر این شما برای اعمال مختلف نیاز به ایجاد توابع و متغییر های خاصی خواهین داشت.بازم نوشتن تمام اینها به صورت بالا به پایین بسیار سخت و ... هست.
درواقع با افزایش پیچیدگی برنامه احتمال خرابکاری برنامه توسط داده های قبلی تعریف شده زیاد میشه و کنترل اون هم ملال اور.
ولی با استفاده از متدودولوژی شی گرایی و کلاس بندی هر یک از ویژگی ها میشه به صورت راحتر در موقع نیاز از اونها استفاده کرد.
شما کلاسی برای کنترل میزان روشنایی یه محیط یا یک دستگاه درست میکنین.یک کلاس هم برای کنترل دما و ...
تو این حالت تمام کلاسها به صورت مجزا از هم هستن و احتمال ایجاد تداخل و پیچیدگی به حداقل میرسه.شما یک شی از کلاس تنظیم روشنایی درست میکنین و با استفاده از اون میزان روشنایی محیط را با استفاده ازمقادیر و فیلدهایی که تو کلاس مورد نظر ایجاد کردین انجام میدین و همینطور بقیه...
متغییرهایی که توی کلاس تعریف میشن معمولا مخفی و محافظت شده هستن تا از بیرون به طور مستقیم دست کاری نشن.اگه شما دوتا متغییر هم نام تعریف کنین این مورد مشهوده.هرکدوم تو کلاس و حیطه ی خودشون فعالیت میکنن و با همدیگه کاری ندارن.
البته تو برنامه نویسی ساخت یافته هم مواردی مثل استراکت یا ساختار هست که شبیه کلاس عمل میکنه ولی نه کاملا.
برای کلاسها موارد دیگه ای مثل وراثت و ... هم هست که اگه تحقیق و مطالعه کنین پی میبرین که تمام این موارد برای راحتی و افزایش کارایی برنامه تو نرم افزارهای پیچیده هست.
و در واقع بدون مبحث شی گرایی و کلاس بندی رشد صنعت نرم افزار اون طوری که الان هست غیر ممکن بود.
dr-data
یک شنبه 02 بهمن 1390, 16:17 عصر
سلام.
ممنون از توجه شما،مفهوم رو متوجه شدم ولي باز فرقشو با فانكشن نفهميدم!:متفکر: ببينيد خب توي فانكشن هم ما همچين كاري ميكنيم ديگه، مثلاً يه فانكشن مي نويسيم كه دماي محيط وروديش باشه و مثلاً درجه زيادي يا كمي گرم كننده خروجي فانكشن هستش، و به همين ترتيب براي هر كاري يه فانكشن مي نويسيم و در مواقع نياز فراخوانيش ميكنيم ديگه! نه؟:اشتباه: بعد كلاس رو هم مثل فانكشن قبل از تابع main و در ابتداي برنامه تعريف مي كنيم؟ يعني اول كل كلاسها رو مثل فانكشن اول برنامه تعريف مي كنيم و بعد ازشون استفاده مي كنيم؟؟ اگه فرقشو با تابع باز كنيد ممنون ميشم.
اگه بتونيد يه مثال به صورت كد نويسي توي مثلاً visual studio 2008 بنويسيد خيلي ممنون ميشم. بعد اين public و private چيه؟ :متفکر:
اگه يه مثال به صورت كد نويسي شده بياريد فكر كنم خيلي بهتر ميتونم بفهمم و مشكلم حل ميشه.
ببخشيد من كند ذهن نيستماا:لبخند: ولي خب چون هيچ كلاسي در زمينه برنامه نويسي نرفتم اين مسائل پايه اي و تعريفي برام پيش مياد.
بازم ممنون.
cpppro
یک شنبه 02 بهمن 1390, 17:51 عصر
سلام
درسته توی تابع هم میشه این کارها رو کرد.در واقع توی کلاس هم معمولا از یک یا چند تابع استفاده میشه.ولی اگه به فرض شما تمام توابع رو بخایین کنار تابع اصلی بیارین برنامه شما اونقدر بزرگ میشه که از کنترل خارج میشه.تشابه اسمها ، تداخل در کار متغییرها و ...
نه کلاس رو معمولا بصورت جداگانه تعریف میکنن تا برنامه قابل تفکیک باشه.بعد شما همون توابع رو میایین و داخل اون کلاس تعریف میکنین.حالا وقتی میخوایین توی برنامه اصلی از اون توابع استفاده کنین خیلی راحت اگه تابع استاتیک باشه که مستقیما در ادامه نام کلاس میتونین بیارین وگرنه اول یه شی از اون کلاس ایجاد میکنین و بعدا میتونین از توابع و فیلدهای تعریف شده تو کلاس استفاده کنین.
حالت ها public و private هم برای در امان ماندن متغییر ها یا توابع و ... از دست کاری مستقیم داده ها توسط کلاسهای دیگه یا همون تابع اصلی هست.شما اگه یه تابع رو پابلیک اعلان کنین تو همه جای برنامه میشه خیلی راحت اون رو فراخانی کرد ولی این کار توی برنامه های پیچیده باعث بهم ریختن نظم و ساختار برنامه و تداخل میشه.
برای مثال شما اگه لوله اگزوز ماشین رو ایزوله و مهروموم نکنین و مثلا یه راه ازش به جلوی هواکش ماشین بزارین ماشین بعد از یه مدت با افت عملکرد و تداخل تو کارش روبرو میشه.(هر کدوم یه وظیفه ی خاص دارن)
تو زبانهای شی گرای جدید مثل سی شارپ معمولا تمام کارها رو کلاسهاست .حتی اگه دقت کنین تابع اصلی هم داخل یه کلاس تعریف شده.
یه مثال براتون گذاشتم . تو این برنامه من کلاس رو در کنار تابع اصلی برنامه قرار دادم ولی معمولا برای ایجاد کلاس از یه روش دیگه استفاده میشه تا خوانایی برنامه بیشتر بشه ، یعنی میتونین از solution Explorer از قسمت add یه کلاس به برنامه اضافه کنین و عملیات داخل اون رو تو یه صفحه ی جداگانه پیاده سازی کنین.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args) // تابع اصلی
{
int k1 = 10, k2 = 20; // تعریف دو متغییر در تابع اصلی
function(k1, k2); // فراخانی تابع
program_2 object1=new program_2(); // ایجاد یک شی از کلاس
program_2 object2 = new program_2(); // ایجاد یک شی از کلاس
string obj = object1.Func.ToString(); // استفاده از همان شی برای گرفتن مقدار محاسبه شده در کلاس
Console.WriteLine("class out : {0}",obj); // خروجی
string obj2 = object2.function2(k1, k2).ToString() ;
Console.WriteLine("class out 2 : {0}",obj2); // خروجی
Console.WriteLine("static class out : {0}", program_2.feild1);// خروجی مقادیر استاتیک
Console.WriteLine("static class out : {0}", program_2.feild2);
Console.ReadLine();
}
static void function(int x, int y) // یک تابع
{
Console.WriteLine("output : {0}", x + y);
}
//************************* تعریف یک کلاس جدید
class program_2
{
private int k1 = 30, k2 = 50; // تعریف متغییر های اختصاصی
public static string feild1 = "salam"; // تعریف متغییر های استاتیک و عمومی
public static string feild2 = " hi";
public int d1 = 2, d2 = 3; // متغییر عمومی
public program_2() // تابع سازنده ی کلاس برای تخصیص دهی اولیه
{
Func = function(d1, d2);
function2(k1, k2);
}
public int Func // پروپرتی های مربوطه
{
set
{
value = k1 = 200; // قرار دادن مقادیر
value = k2 = 300;
}
get
{
return function(k1,k2) ; // برگشت مقادیر
}
}
private int function(int x, int y) // تابع عضو کلاس خصوصی
{
return x + y;
}
public int function2(int x, int y) // تابع عضو کلاس عمومی
{
return x + y;
}
}
}
}
این مثال رو میتونین توی سی پلاس پلاس هم به راحتی پیاده سازی کنین :)
dr-data
یک شنبه 02 بهمن 1390, 20:47 عصر
سلام cpppro عزيز.
آقا ممنون از توجهتون ولي اين خيلي پيشرفتس :متعجب: زير ديپلم برنامه نويسي بگيد لطفا:چشمک:
بعد به نظر من كه اين الان پيچيده تر شده كه! ما ميايم يه كلاس تعريف ميي كنيم بعد توش دوباره از فانكشن استفاده مي كنيم؟!!!!!!:عصبانی++: چه كاريه؟ البته نمي خوام فلسفه برنامه نويسي شي گرا رو ببرم زير سوالها:بامزه: حتماً و 200% اينكار يه سودي داره كه ميشه اثباتش كرد! ببخشيدا اگه سوالم خيلي ابتدائيه واس شما نرم افزاريهاي عزيز:افسرده:
اگه بتونيد همون مثالي كه در مورد مثلاً كنترلر دما و مثلاً نور هست رو با كلاس بنويسيد خيييليييي ممنون ميشم.
من الگوريتم رو ميگم:
متغير hin حاوي دماي اندازه گيري شدس و متغير hout يه عدده كه هر چي مقدارش بيشتر باشه يعني دما رو بيشتر كن و هرچي كمتر يعني دما رو كمتر كن.
فرمول هم مثلاً اينه: hout=hin*5
متغير lin حاوي دماي اندازه گيري شدس و متغير lout يه عدده كه هر چي مقدارش بيشتر باشه يعني نور رو بيشتر كن و هرچي كمتر يعني نور رو كمتر كن.
فرمول هم مثلاً اينه: lout=lin*8
الان من واس نوشتن اين با فانكشن مشكلي ندارم. اگه ميشه اينو با كلاس بنويسيد .
ممنون.
cpppro
دوشنبه 03 بهمن 1390, 08:40 صبح
سلام
این برنامه پیچیده به نظر میرسه چون کوچیک هست.درواقع تو برنامه های کوچک روش ساخت یافته آسونتره ولی وقتی برنامه بزرگتر بشه(چند صد هزار خط ) کنارهم گذاشتین این همه تابع و متغییر سرگیجه اور خواهد بود.
مسئله ی شما رو الان با کلاس پیاده سازی کردم.بازم اینجا کلاس رو در کنار تابع اصلی تعریف کردم که زیاد کار جالبی نیست ولی تنها برای نمایش کلی برنامه هست.اگه برنامه رو اجرا کنین به طور صحیح اجرا خواهد شد.
از دو روش استفاده شده .یکی با استفاده از پروپرتی و تعریف اشیا و یکی هم که اسونتره با استفاده از متغییرهای استاتیک که استفاده از اونها میتونه به صورت مستقیم انجام بشه.
مثلا تو اینجا مقدار وارد شده از صفحه کلید رو مستقیما توی متغییر hin2 از کلاس program_1 قرار میده
program_1.hin2 = Convert.ToInt32(Console.ReadLine());
اما کله برنامه :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
// روش اول ایجاد شی از کلاس و استفاده از آن
program_1 object1=new program_1();
object1.HIN = Convert.ToInt32(Console.ReadLine());
program_1 object2 = new program_1();
object2.LIN = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("output for hout : {0}" , object1.HIN); // خروجی
Console.WriteLine("output for lout : {0}" , object2.LIN);
//****** روش دوم
program_1.hin2 = Convert.ToInt32(Console.ReadLine());
program_1.lin2 = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("output for hout2 : {0}", program_1.func1()); // فراخانی مستقیم تابع استاتیک
Console.WriteLine("output for lout2 : {0}", program_1.func2());
//^^^^^^
Console.ReadLine();// stop
}
class program_1
{
private int hin ; // متغییر های خصوصی
private int lin ;
private int hout=0, lout=0;
public program_1()// تابع سازنده کلاس
{
}
public int HIN // پروپرتی 1
{
set { hin=value; } // مقدار وارد شده را در این متغییر قرار بده
get { return function1(); } // مقدار بدست آمده را به بیرون از کلاس برگشت بده
}
public int LIN // پروپرتی 2
{
set { lin=value; }
get { return function2(); }
}
private int function1()// تابع 1
{
return hout = hin * 5;
}
private int function2() // تابع 2
{
return lout = lin * 8;
}
//********************** روش دوم با استفاده از متغییر های استاتیک
public static int hin2, lin2, hout2 = 0, lout2 = 0; // تعریف متغییر های استاتیک
public static int func1() // تابع اول استاتیک
{
return hout2 = hin2 * 5;
}
public static int func2() // تابع دوم استاتیک
{
return lout2 = lin2 * 8;
}
}
}
}
dr-data
دوشنبه 03 بهمن 1390, 09:34 صبح
سلام آقا مرسي 70% مشكلمو حل كرديد:چشمک:
من بعد از اين حرف شما كه" تعريف كلاس در كنار تابع اصلي كار خوبي نيست"، كلي دوباره سرچ كردم آخر فهميدم فايده اينكار چيه!!
فايدش اينه كه ما كلاس رو توي header file ها تعريف مي كنيم بعد توي برنامه Include مي كنيمش:تشویق:
خب مهندس بگووو ديگه از اول:چشمک: اين شد يه چيزي، اين طوري بله كاملاً فايدش مشهود شد! به قول شما اگه يه برنامه با 10000000 خط داشته باشيم اينكار خيليييييي كار رو آسون ميكنه.
فقط 4 سوال ديگه!
1) يعني توي زبان c اين قابليت وجود نداشت؟
2) سوال دوم هم اينه كه توي visual studio 2008 چطوري ميشه class رو توي فايل .h نوشت كه بعد بتونيم فراخوانيش كنيم؟
3) تابع رو نميشه اينطوري به صورت مجزا تعريف كرد و بعد توي برنامه هاي مختلف استفاده كرد؟
4) سوال اخر كه خيلي بچه گونس ولي مهم اينه كه پس اگه ما برناممونو بر اساس تعريف فانكشن و... در كنار تابع main تعريف كنيم، به اين روش برنامه نويسي ميگيم stractural و اگر از كلاس ها استفاده كنيم ميگيم object oriented درسته؟
خيلي ممنوووووون
cpppro
دوشنبه 03 بهمن 1390, 11:35 صبح
سلام
درسته اساس شی گرایی بسته بندی و کپسوله کردن اشیا و ویژگیها هستش تا بشه بر پیچیدگی غلبه کرد.
شما یه کلاس میسازین و تمام محاسبات و توابع مورد نیاز رو توش استفاده میکنین و موقع نیاز اون رو فراخانی کرده و به برنامه اصلی پیوند میزنین.
درواقع توی یه کلاس میتونه صدها تابع و متغییر و ... تعریف بشه.(البته تمام این توابع مربوط به کار خاصی هستن که اون کلاس پیاده سازی میکنه)
تو زبان c قدیمی این قابلیتها نیست و توی سی پلاس پلاس مفهموم شی گرایی و کلاس بندی بعدا ارائه شده.البته زبانی به نام objective c هستش که توسعه یافته ی زبان سی هست و همین مفهموم کلاس و ... توی اون هم هست.
البته اگه بگردین مطلبی با عنوان ساختار توی زبان سی و سی پلاس پلاس هست که تا حدودی شبیه کلاس عمل میکنه ولی قابلیتهای اون محدود هست.
درسته با include و اوردن نام کلاس میتونین ازش تو برنامه استفاده کنین.
درواقع کلاس شما یه ماژول مجزا میشه که همه جا میتونین ازش بسته به کاربرد استفاده کنین. :)
البته بحث شی گرایی تنها به تعریف کلاس محدود نمیشه. بحث وراثت ، چند ریختی و ... هم هست.ولی مفاهیم اصلی مدل شی گرایی به این صورت تعریف میشن :
بسته بندی یا کپسوله سازی
تجرید و چکیده سازی
واحد بندی
سلسله مراتب
که هرکدوم بحث خاص خودشون رو دارن.توصیه میکنم از یه کتاب ساده شروع کنین و به تدریج این مباحث رو بکار بگیرین تا بتونین به طور کامل ازشون تو برنامه ها استفاده کنین :)
dr-data
دوشنبه 03 بهمن 1390, 14:21 عصر
سلام مرسي cpppro جان از كمك.
راستي كتاب ديتل ديتل خوبه بگيرم؟ اون توي محيط visual studio توضيح داده؟ اگه نه كتابي كه توي visual studio توضيح داده باشه و خوب هم باشه و زيادم حرفه اي نباشه چي بگيرم؟ حرفه اي نباشه يعني در همين حد ديتل ديتل كافيه ولي توي محيط visual studio.
يه سوال حاشيه اي هم دارم كه به اين پست مربوط نميشه ولي اگه بگيد ممنون ميشم. در برنامه نويسي pc و همين c++ خودمون چطوري ميشه تاخير ايجاد كرد؟ يعني مثلاً مي خوايم بعد از true شدن يه متغير bool مثلاً 10 ثانيه صبر كنيم (wait)
ممنون
cpppro
دوشنبه 03 بهمن 1390, 14:43 عصر
سلام
آره خوبه
من الان کتاب دیتل 2005 رو دارم(البته اینگلیسی).خیلی خوب توضیح داده.کداشم رنگیه و تفکیک کدا راحت . اگه اینگلیسی خون بودین براتون اپلود میکنم . :)
ولی بهتره اول از یه کتاب فارسی شروع کنین.دیتیل فقط کمی مفصل توضیح داده.شاید برا شروع یکم حوصلتون رو سر ببره.اگه جعفرنژاد دم دست داشتین از اون شروع کنین.دفعه ی بعد برای تکرار و تمرین دیتیل رو هم بخونین :)
اینم بگم دیتیل جدید با استاندارهای جدید سی پلاس پلاس سازگارتره.بعضی از کدای کتاب جعفرنژاد با VS2008 و ... سازگار نیستن(مال دهه 90 هست).
یه قسمت از کتاب دیتیل :
http://s1.picofile.com/file/7261194187/untitled.png
dr-data
دوشنبه 03 بهمن 1390, 16:31 عصر
سلام
cpppro جان داشتييييييم؟!! مسخره كردي ديگهههه؟ باشهههه:بامزه:
آقا من ارشد برق ميخونم با انگليسي مشكلي ندارم اتفاقاً راحتتر از اين ترجمه هاي اساتيد محترممونم :چشمک:
من كتاب ديتل ديتل كه با فرمت chm هستش رو دارم. اگه بتونيد كدها و محتويات cd همراهشو آپلود كنيد خيلي ممنون ميشم. هرچي گشتم پيدا نكردم متاسفانه.
راستي به اون سوال delay هم اگه ميشه يه پاسخي بدين.
بازم ممنون از توجه شما.
cpppro
دوشنبه 03 بهمن 1390, 18:17 عصر
بله :)
شرمنده . یه اشاره ای یه ...
ایشالا که تو همه جا موفق باشین :)
نه متاسفانه کدا رو ندارم.ولی فکر کنم اگه بگردین تو اینترنت پیدا میشه.
برای ایجاد تاخیر معمولا از تایمر استفاده میشه.بصورت دستی هم میشه نوشت.فکر کنم تو زبان اسمبلی از چنتا حلقه برای توقف چند ثانیه ای استفاده میشد. برای این کار توابع و ... هم توی هر کامپایلر به صورت جداگانه وجود داره.مثل : Sleep(5000);
یا با استفاده از تردها
#using <mscorlib.dll> using namespace System; using namespace System::Threading; static TimeSpan waitTime = TimeSpan(0, 0, 1); __gc class Test { public: static void Work() { Thread::Sleep(waitTime); } }; void main() { Thread* newThread = new Thread(new ThreadStart(0, Test::Work)); newThread->Start(); if(newThread->Join(waitTime + waitTime)) { Console::WriteLine(S"New thread terminated."); } else { Console::WriteLine(S"Join timed out."); } }
یا مثل این : http://msdn.microsoft.com/en-us/library/aa332371%28v=vs.71%29.aspx
اینم با استفاده از CFileTimeSpan
#include "stdafx.h"
#include "iostream"
#include "atltime.h"
int _tmain(int argc, _TCHAR* argv[])
{
CFileTime now=CFileTime::GetCurrentTime();
int j=0;
for(int i=0;i<2032100000;i++)
{
j++;
j--;
}
CFileTimeSpan twoWeeksAgo =CFileTime::GetCurrentTime()- now;
return 0;
}
dr-data
دوشنبه 03 بهمن 1390, 22:15 عصر
آقا خيلييييييي ممنون از تمامي كمكاتت:چشمک:
mohsen_popo
شنبه 08 بهمن 1390, 04:57 صبح
سلام دوست عزیز
اکه میخوای برنامه نویسی visual studio2008 کارکنی و یاد بگیری بهتر کتاب (چگونه با c# برنامه نویسی کنیم ) بخری خیلی خیلی کتاب جامع......نویسندش بهرام پاشایی
در ضمن.....کلاس در visual studio خانه ی تمامی توابه ،متغیر..........................هستش.... .......تو نمیتونی متغیری را خارج کلاس تعریف کنی اکه این کارو کنی ارور میگیره.....در حالای که تو بر نامه نویسی های دیگه میتونی......................و تمام تو ضیحات جامع رو هم که بهت دادن
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.