Sorunun Tarihi
C++'da sınıf statik üyeleri, tüm nesneler için ortak bir değer veya belirli bir sınıf örneğine bağlı olmayan bir fonksiyon saklamaya olanak tanımak için ortaya çıkmıştır. Bu, sayıcılar, nesne fabrikaları veya yardımcı fonksiyonlar gibi şeyleri saklamak için kullanışlıdır.
Sorun
Her zaman zorluklardan biri, bu tür üyelerin kapsamı ve başlatılma anıydı, özellikle programda çok sayıda kaynak dosyası olduğunda. Statik bir üyenin yanlış tanımlanması, bağlayıcı hatalarına (linker errors) yol açar.
Çözüm
C++'da statik üyeler sınıf tanımında bildirilir, ancak başlatma (değişkenler için) ayrı bir cpp dosyasında olmalıdır (C++17 öncesi). C++17, eğer constexpr ise, doğrudan bildirim içinde başlatmaya izin verir.
Kod örneği:
class MyClass { public: static int counter; static void increment() { ++counter; } }; int MyClass::counter = 0; // sınıf dışı başlatma ZORUNLUDUR
Ana özellikler:
Eğer cpp dosyasında statik üye tanımlanmazsa ne olur?
Bağlayıcı hatası alırsınız, çünkü statik değişken tanımlanmış, fakat tanımsızdır. Hariç durum — eğer static const int sınıf içinde doğrudan constexpr değeri için başlatılmışsa.
// .h class A { public: static int x; }; // .cpp // int A::x = 0; // yorumlanırsa - hata alırsınız
Statik bir fonksiyondan statik olmayan bir fonksiyon çağrılabilir mi?
Hayır. Statik fonksiyona this işaretçisi ve statik olmayan üyelere doğrudan erişilemez. Erişim için belirli bir nesne gerekir.
class B { int data; static void foo() { // data = 3; // hata } };
Statik değişkenler tüm örnekler için ortak mıdır?
Evet, aynı yürütme dosyasındaki ve süreçteki her örnek için aynı değerdir.
Ekip, cpp dosyasında statik üyeyi tanımlamayı unuttu, proje ara sıra hata ile derleniyor ve bazen inline başlatma kullanıldığında (tüm derleyicilerde değil) "gizemli" bir çalışma hatası ortaya çıkıyor.
Artılar:
Eksiler:
Şirket içinde kural şu: statik üyeler her sınıf için cpp dosyalarında tanımlıdır. İş parçacığı güvenliği için std::mutex veya atomik işlemler kullanılır.
Artılar:
Eksiler: