اخرین بروزرسانی: 08.10.2017

علاوه بر متغیرها و متدهایی که مستقیماً با شی مرتبط هستند، C++ به شما این امکان را می دهد که متغیرها و متدهایی را تعریف کنید که مستقیماً با کلاس یا موارد دیگر مرتبط هستند. اعضای ثابتکلاس متغیرها و متدهای استاتیک به طور کلی به کل کلاس اشاره دارند. برای تعریف آنها از کلمه کلیدی ثابت استفاده می شود.

به عنوان مثال، یک بانک ممکن است دارای سپرده های مختلف باشد، اما همه سپرده ها دارای برخی نرخ های بهره مشترک خواهند بود. بنابراین، برای توصیف یک حساب بانکی، کلاس زیر را تعریف و استفاده می کنیم:

#عبارتند از class Account ( public: Account(doublesum) ( this->sum = sum; ) static int getRate() ( rate return; ) static void setRate(int r) ( rate = r; ) double getIncome() ( جمع برگشتی + مجموع * نرخ / 100؛ ) خصوصی: مجموع دو برابر؛ نرخ int ثابت؛ )؛ حساب int::rate = 8; int main() ( Account account1(20000); Account account2(50000) Account::setRate(5); // reset rate std::cout<< "Rate: " << Account::getRate() << std::endl; std::cout << "Rate: " << account1.getRate() << " Income: " << account1.getIncome() << std::endl; std::cout << "Rate: " << account2.getRate() << " Income: " << account2.getIncome() << std::endl; return 0; }

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

علاوه بر این، شما نمی توانید از این نشانگر در توابع استاتیک استفاده کنید، که در اصل بدیهی است، زیرا به شی فعلی اشاره می کند، و توابع استاتیک به کل کلاس به عنوان یک کل اشاره می کنند.

همچنین مهم است که اگر کلاس دارای متغیرهای ثابت باشد، آنها باید به طور اضافی خارج از کلاس تعریف شوند:

حساب بین المللی::rate = 8;

لازم نیست مقدار اولیه را به یک متغیر اختصاص دهید.

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

حساب::getRate() account1.getRate()

خروجی کنسول برنامه:

نرخ: 5 نرخ: 5 درآمد: 21000 نرخ: 5 درآمد: 52500

همچنین، ثابت استاتیک اغلب در کلاس ها استفاده می شود. برای مثال، بیایید نرخ متغیر را در کلاس Account ثابت کنیم:

#عبارتند از class Account ( public: const static int rate = 8; Account (double sum) ( this->sum = sum; ) double getIncome() ( return sum + sum * rate / 100; ) private: double sum; ); int main() ( Account account1(20000); Account account2(50000); std::cout<< "Rate: " << account1.rate << "\tIncome: " << account1.getIncome() << std::endl; std::cout << "Rate: " << account2.rate << "\tIncome: " << account2.getIncome() << std::endl; return 0; }

برخلاف متغیرهای استاتیک، ثابت های استاتیک نیازی به تعریف بیشتر در خارج از کلاس ندارند.

علاوه بر اصلاح کننده دسترسی، می توانید یک کلمه کلیدی را قبل از نام یک فیلد، روش یا ویژگی بنویسید ایستا .
« ایستا " به این معنی است که فیلد، متد یا ویژگی داده شده به هر شی از کلاس تعلق نخواهد داشت، بلکه به همه آنها با هم تعلق دارد.

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

بیایید به مثال ببرها نگاه کنیم. بیایید کلاس را تعریف کنیم " ببر". اگر فیلد کلاس را به صورت زیر بنویسیم: تعداد int عمومی;سپس هر شیء دارای این فیلد خواهد بود، و هر شیء مختص به خود را خواهد داشت. علاوه بر این، اگر یک شیء واحد ایجاد نشود، این فیلد اصلا وجود نخواهد داشت.
بنابراین، بیایید این فیلد را ثابت کنیم ( ایستا).

بیایید سازنده ای ایجاد کنیم که در آن شمارنده را افزایش می دهیم شمردنهنگام ایجاد هر شی جدید:
public Tiger() (count++; ).
در اینجا ما همچنین می توانیم ویژگی های فردی ببر را تنظیم کنیم: وزن، قد، نام مستعار.

ما همچنین یک متد استاتیک خواهیم نوشت که تعداد اشیاء ایجاد شده را نشان می دهد:
خالی استاتیک عمومی ShowNumberOfObjects().

سپس برنامه کنسول ما دو کلاس خواهد داشت:

کلاس عمومی Tiger ( تعداد int static عمومی; عمومی Tiger() ( count++; ) public static void ShowNumberOfObjects() ( Console.WriteLine("Tigers = (0)", Tiger.count.ToString()); ) ) class Program ( static void Main(string args) ( // تعداد ببرها بدون ایجاد اشیا چقدر است؟ Tiger.ShowNumberOfObjects(); // 0 چون هنوز اشیایی ایجاد نکرده ایم // ایجاد 3 ببر Tiger t1 = ببر جدید (); Tiger t2 = ببر جدید (); Tiger t3 = ببر جدید (); Tiger.ShowNumberOfObjects(); // 3 ببر بیرون خواهند آمد Console.ReadLine(); ) )

نتیجه: 3.

نتیجه. یک روش استاتیک به شما امکان می دهد بدون داشتن هیچ شیئی آن را فراخوانی کنید. به جای نام شی، هنگام فراخوانی متد، نام کلاس Tiger مشخص می شود: Tiger.ShowNumberOfObjects();

تفاوت بین روش استاتیک و غیر استاتیک:

1. برای فراخوانی یک متد استاتیک به شی نیاز ندارید.
2. در داخل متد static، این متغیر که به شی اشاره می کند، در دسترس نیست؛ بر این اساس، تمام فیلدهای غیر استاتیک این کلاس در دسترس نیستند، زیرا مثل هیچ شی
3. در یک روش معمولی، هم فیلدهای استاتیک و هم غیراستاتیک موجود است.
4. با شروع با C# 4.0، امکان ثابت کردن خود کلاس فراهم شد.

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

حال بیایید به مفهوم "ساختار" بپردازیم و تفاوت آن را با یک کلاس دریابیم.

آخرین به روز رسانی: 1397/12/25

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

اکانت کلاس ( پاداش اعشاری ثابت عمومی = 100؛ مجموع اعشاری عمومی؛ مجموع اعشاری عمومی؛ حساب عمومی (جمع اعشاری) ( مجموع مجموع = مجموع + پاداش؛ ) ) برنامه کلاس (خلأ ثابت اصلی (رشته آرگ) ( Console.WriteLine (Account.bonus)؛ / / 100 Account.bonus += 200;Account account1 = new Account(150);Console.WriteLine(account1.totalSum)؛ // 450 Account account2 = new Account(1000);Console.WriteLine(account2.totalSum); // 1300 Console.ReadKey(); ))

در این حالت، کلاس Account دارای دو فیلد است: bonus و totalSum. فیلد پاداش ثابت است، بنابراین وضعیت کلاس را به عنوان یک کل ذخیره می کند، نه یک شی واحد. و بنابراین می توانیم به این فیلد با نام کلاس اشاره کنیم:

Console.WriteLine(Account.bonus); Account.bonus += 200;

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

در همان زمان، حافظه برای متغیرهای استاتیک تخصیص داده می شود حتی اگر هیچ شیئی از این کلاس ایجاد نشده باشد.

خواص و روش های استاتیک

به همین ترتیب، می‌توانیم روش‌ها و ویژگی‌های استاتیک را ایجاد و استفاده کنیم:

حساب کلاس (حساب عمومی (جمع اعشاری، نرخ اعشاری) (اگر (جمع< MinSum) throw new Exception("Недопустимая сумма!"); Sum = sum; Rate = rate; } private static decimal minSum = 100; // минимальная допустимая сумма для всех счетов public static decimal MinSum { get { return minSum; } set { if(value>0) minSum = مقدار; ) ) جمع اعشاری عمومی ( دریافت؛ مجموعه خصوصی؛ ) // مبلغ روی حساب نرخ اعشاری عمومی ( دریافت؛ مجموعه خصوصی؛ ) // نرخ بهره // محاسبه مبلغ روی حساب پس از یک دوره معین با نرخ معین عمومی اعشاری ایستا GetSum (جمع اعشاری، نرخ اعشاری، دوره میانی) (نتیجه اعشاری = مجموع؛ برای (int i = 1؛ i<= period; i++) result = result + result * rate / 100; return result; } }

متغیر minSum، ویژگی MinSum و متد GetSum در اینجا با کلمه کلیدی static تعریف می شوند، به این معنی که ثابت هستند.

متغیر minSum و ویژگی MinSum حداقل مقدار مجاز برای ایجاد یک فاکتور را نشان می دهد. این شاخص به هیچ حساب خاصی اشاره نمی کند، بلکه به طور کلی برای همه حساب ها اعمال می شود. اگر این اندیکاتور را برای یک حساب تغییر دهیم، باید برای حساب دیگر نیز تغییر کند. یعنی برخلاف خصوصیات Sum و Rate که وضعیت یک شی را ذخیره می کنند، متغیر minSum وضعیت را برای تمام اشیاء یک کلاس مشخص ذخیره می کند.

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

بنابراین، متغیرها و ویژگی هایی که حالت مشترک همه اشیاء یک کلاس را ذخیره می کنند باید به عنوان ثابت تعریف شوند. و همچنین روش هایی که رفتار مشترک برای همه اشیا را تعریف می کنند نیز باید به عنوان ثابت اعلام شوند.

اعضای ایستا یک کلاس برای همه اشیاء آن کلاس مشترک هستند، بنابراین باید با نام کلاس به آنها اشاره کرد:

توجه داشته باشید که متدهای استاتیک فقط می توانند به اعضای استاتیک یک کلاس دسترسی داشته باشند. ما نمی‌توانیم به روش‌های غیراستاتیک، فیلدها، خصوصیات درون یک متد استاتیک اشاره کنیم.

اغلب از فیلدهای ثابت برای ذخیره شمارنده ها استفاده می شود. به عنوان مثال، فرض کنید یک کلاس User داریم و می‌خواهیم یک شمارنده داشته باشیم که به ما بگوید چند شیء کاربر ایجاد شده است:

Class User ( private static int counter = 0; public User() ( counter++; ) public static void DisplayCounter() ( Console.WriteLine($"Created (counter) User Objects"); ) ) class Program ( static void Main(string args) ( کاربر 1 = کاربر جدید ( ؛ کاربر کاربر 2 = کاربر جدید ( ؛ کاربر کاربر 3 = کاربر جدید ( ؛ کاربر کاربر 4 = کاربر جدید ( ؛ کاربر کاربر 5 = کاربر جدید ( ؛ User.DisplayCounter ( ) ؛ / / 5 Console.ReadKey(); ))

سازنده استاتیک

علاوه بر سازنده های معمولی، یک کلاس می تواند سازنده های ایستا نیز داشته باشد. سازنده های استاتیک دارای ویژگی های متمایز زیر هستند:

    سازنده های استاتیک نباید اصلاح کننده دسترسی داشته باشند و هیچ پارامتری دریافت نکنند

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

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

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

بیایید یک سازنده استاتیک تعریف کنیم:

کاربر کلاس ( کاربر ثابت user2 = کاربر جدید(); Console.Read(); ))

کلاس های استاتیک

کلاس‌های استاتیک با اصلاح‌کننده استاتیک اعلان می‌شوند و فقط می‌توانند شامل فیلدها، ویژگی‌ها و متدهای استاتیک باشند. به عنوان مثال، اگر کلاس Account فقط دارای متغیرها، ویژگی‌ها و متدهای ثابت باشد، می‌توان آن را به عنوان ثابت اعلام کرد:

کلاس ایستا حساب (حساب اعشاری استاتیک خصوصی minSum = 100؛ // حداقل مقدار مجاز برای همه حساب ها حداقل جمع اعشاری ثابت عمومی ( دریافت ( بازگشت minSum; ) مجموعه ( if(value>0) minSum = مقدار; ) ) // محاسبه حساب مقدار پس از یک دوره معین با یک نرخ معین اعشاری استاتیک عمومی GetSum (جمع اعشاری، نرخ اعشاری، دوره int) (نتیجه اعشاری = مجموع؛ برای (int i = 1; i<= period; i++) result = result + result * rate / 100; return result; } }

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

درس 25

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

    C++ به شما اجازه می دهد که اشیایی از یک نوع داشته باشید که یک یا چند عضو از یک کلاس را به اشتراک بگذارند.

    اگر برنامه شما مقداری را به یک عنصر مشترک اختصاص دهد، تمام اشیاء آن کلاس بلافاصله به آن مقدار جدید دسترسی خواهند داشت.

    برای ایجاد یک عضو داده مشترک کلاس، باید نام عضو کلاس را با کلمه کلیدی پیشوند قرار دهید ایستا

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

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

موارد به اشتراک گذاشته شده

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

private: static int shared_value;

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

int class_name::shared_value;

برنامه زیر SHARE_IT.CPP کلاس را تعریف می کند سری کتاب ها،عنصر اشتراک گذاری page_count،که برای تمام اشیاء (کتاب) یک کلاس (سری) یکسان است. اگر برنامه مقدار این عنصر را تغییر دهد، تغییر بلافاصله در تمام اشیاء کلاس منعکس می شود:

#عبارتند از

#عبارتند از

سری_کتاب کلاس

( public: book_series (char *, char *, float); void show_book (void); void set_pages(int) ؛ private: static int page_count; char title; char author[ 64 ]; float price; );

int book_series::page__count;

void book_series::set_pages(int pages)

(page_count = صفحات؛ )

book_series::book_series(char *عنوان، کاراکتر *نویسنده، قیمت شناور)

( strcpy(کتاب_سری::عنوان، عنوان); strcpy(مجموعه_کتاب::نویسنده، نویسنده)؛ سری_کتاب::قیمت = قیمت؛ )

void book_series::show_book(void)

(کوت<< "Заголовок: " << title << endl; cout << "Автор: " << author << endl; cout << "Цена: " << price << endl; cout << "Страницы: " << page_count << endl; }

( برنامه نویسی book_series ("یادگیری برنامه نویسی در C++"، "Jamsa"، 22.95); word_series word("آموزش استفاده از Word برای ویندوز"، "Wyatt"، 19.95); word.set_pages(256); programming.show_book () ؛ word.show_book() ؛ cout<< endl << "Изменение page_count " << endl; programming.set_pages(512); programming.show_book(); word.show_book(); }

همانطور که می بینید، کلاس اعلام می کند page_countچگونه استاتیک بینبلافاصله پس از تعریف کلاس، برنامه یک عنصر را اعلام می کند page_countبه عنوان یک متغیر جهانی وقتی یک برنامه یک عنصر را تغییر می دهد page_count،تغییر بلافاصله در تمام اشیاء کلاس منعکس می شود سری کتاب ها.

اشتراک گذاری اعضای کلاس

بسته به برنامه شما، ممکن است شرایطی وجود داشته باشد که لازم باشد داده های خاصی را بین چندین نمونه از یک شی به اشتراک بگذارید. برای انجام این کار، چنین عنصری را ثابت اعلام کنید. بعد، این عنصر را خارج از کلاس به عنوان یک متغیر جهانی اعلام کنید. هر تغییری که برنامه شما در این عنصر ایجاد کند بلافاصله در اشیاء این کلاس منعکس می شود.

استفاده از عناصر با ویژگیعمومی ایستا اگر اشیاء وجود ندارند

همانطور که تازه یاد گرفتید، هنگام اعلام عضوی از یک کلاس به عنوان ایستااین عنصر توسط تمام اشیاء کلاس داده شده مشترک است. با این حال، ممکن است شرایطی وجود داشته باشد که برنامه هنوز شی را ایجاد نکرده باشد، اما باید از عنصر استفاده کند. برای استفاده از یک عنصر، برنامه شما باید آن را به صورت اعلام کند عمومیو ایستابه عنوان مثال، برنامه زیر USE_MBR.CPP از عنصر استفاده می کند page_countاز کلاس سری کتاب ها،حتی اگر اشیاء این کلاس وجود نداشته باشند:

#عبارتند از

#عبارتند از

سری_کتاب کلاس

( public: static int page_count; private: char title ; char نویسنده; float price; );

int book_series::page_count;

void main(void) (book_series::page_count = 256; cout<< "Текущее значение page_count равно " << book_series::page_count << endl; }

در این حالت، از آنجایی که کلاس یک عنصر از کلاس را تعریف می کند page_countچگونه عمومی،برنامه می تواند به این عنصر کلاس اشاره کند، حتی اگر اشیاء کلاس سری کتاب هاوجود ندارد.

استفاده از توابع عضو استاتیک

برنامه قبلی کاربرد را نشان داد ایستاعناصر داده به طور مشابه، C++ به شما اجازه تعریف می دهد ایستاتوابع عضو (روش ها). اگر در حال خلق هستید ایستاروش، برنامه شما می تواند آن متد را فراخوانی کند، حتی اگر هیچ شیئی ایجاد نشده باشد. به عنوان مثال، اگر کلاس حاوی متدی است که می تواند روی داده های خارج از کلاس استفاده شود، می توانید این متد را ایجاد کنید ایستادر زیر کلاس است منو،که از دنباله esc درایور ANSI برای پاک کردن صفحه نمایش استفاده می کند. اگر درایور ANSI.SYS را روی سیستم خود نصب کرده اید، می توانید از این روش استفاده کنید شفاف_صفحهبرای پاک کردن صفحه نمایش زیرا این روش به صورت اعلام شده است ایستا،برنامه می تواند از آن استفاده کند حتی اگر اشیا از نوع باشند منووجود ندارد. برنامه زیر CLR_SCR.CPP از روش استفاده می کند شفاف_صفحهبرای تمیز کردن صفحه نمایش:

#عبارتند از

( public: static void clear_screen(void); // روش های دیگر باید در اینجا خصوصی باشند: int number_of_menu_options; );

منوی void::clear_screen(void)

(کوت<< "\033" << "}