اعضای استاتیک
اگر بخواهیم عضو دادهای (فیلد) یا خاصیتی ایجاد کنیم که در همه نمونههای کلاس قابل دسترسی باشد از کلمه کلیدی static استفاده میکنیم. کلمه کلیدی static برای اعضای دادهای و خاصیتهایی به کار میرود که میخواهند در همه نمونههای کلاس تقسیم شوند. وقتی که یک متد یا خاصیت به صورت static تعریف شود، میتوانید آنها را بدون ساختن نمونهای از شی، فراخوانی کنید. به مثالی در مورد متدها و خاصیتهای static توجه کنید :
1: #include<string> 2: #include<iostream> 3: using namespace std; 4: 5: class SampleClass 6: { 7: public: 8: static string StaticMessage; 9: 10: string NormalMessage; 11: 12: static void ShowStaticMessage() 13: { 14: cout << StaticMessage; 15: } 16: 17: void ShowNormalMessage() 18: { 19: cout << NormalMessage; 20: } 21: 22: void ShowStaticFromInstance() 23: { 24: cout << StaticMessage; 25: } 26: }; 27: 28: string SampleClass::StaticMessage = "This is the static message!\n"; 29: 30: int main() 31: { 32: SampleClass sample1; 33: SampleClass sample2; 34: 35: SampleClass::ShowStaticMessage(); 36: 37: cout << endl; 38: 39: sample1.NormalMessage = "Message from sample1!\n"; 40: sample1.ShowNormalMessage(); 41: sample1.ShowStaticFromInstance(); 42: 43: cout << endl; 44: 45: sample2.NormalMessage = "Message from sample2!\n"; 46: sample2.ShowNormalMessage(); 47: sample2.ShowStaticFromInstance(); 48: }
This is the static message! Message from sample1! This is the static message! Message from sample2! This is the static message!
در مثال بالا یک خاصیت استاتیک به نام StaticMessage (خط 8) و یک متد استاتیک به نام ShowStaticMessage() (خطوط 15-12) تعریف کردهایم. وقتی یک عضو داده ای static را در داخل کلاس تعریف می کنید (خط 8)، حافظه به آن اختصاص نمی یابد. در عوض باید در خارج از کلاس، آن را دوباره تعریف و مقداردهی کنید (خط 28). همانطور که در خط 28 مشاهده می کنید، باید قبل از نام متغیر استاتیک، نام کلاس را به همراه علامت دو نقطه بنویسید. مقدار خاصیت StaticMessage در همه نمونههای کلاس SampleClass قابل دسترسی است. متد استاتیک را نمیتوان به وسیله نمونه ایجاد شده از کلاس SampleClass فراخوانی کرد. برای فراخوانی یک متد یا خاصیت استاتیک، به سادگی میتوان نام کلاس و بعد از آن علامت دو نقطه ( :: ) و در آخر نام متد یا خاصیت را نوشت. این موضوع را میتوان در خطوط 28 و 35 مشاهده کرد. مشاهده میکنید که لازم نیست هیچ نمونهای از کلاس ایجاد شود.
همانطور که مشاهده میکنید یک پیغام را به StaticMessage اختصاص دادهایم و با فراخوانی یک متد استاتیک (ShowStaticMessage()) مقدار آن را نمایش میدهیم. در مرحله بعد خاصیت NormalMessage را به وسیله دو نمونه ایجاد شده فراخوانی میکنیم و یک متد را هم برای نشان دادن مقدار آن فراخوانی میکنیم. همانطور که مشاهده میکنید نمونههای ایجاد شده دارای مقدار NormalMessage مخصوص خودشان هستند چون خاصیت NormalMessage غیر استاتیک است.
سپس ShowStaticFromInstance() فراخوانی میکنیم که متدی برای نشان دادن مقدار StaticMessage میباشد. متدهای غیر استاتیک میتوانند از فیلدها و خاصیتهای استاتیک استفاده کنند ولی عکس این قضیه امکان پذیر نیست. به عنوان مثال اگر شما یک متد static داشته باشید نمیتوانید از هر خاصیت، متد، یا فیلدی که static نیست، استفاده کنید.
private: int number = 10; public: static void ShowNumber() { cout << number; //Error: cannot use non-static member }
اصرار بر این کار باعث بروز خطا میشود.