Sınıf statik değişkenleri başlıkta bildirilebilir , ancak tanımlanmalıdır bir .cpp dosyasında . Bunun nedeni, statik değişkenin yalnızca bir örneği olabileceğidir ve derleyici, hangi nesne nesnesini içine koyacağına karar veremez, bunun yerine kararı vermeniz gerekir.
C ++ 11'deki bildirimle statik bir değerin tanımını korumak için iç içe bir statik yapı kullanılabilir. Bu durumda statik üye bir yapıdır ve bir .cpp dosyasında tanımlanması gerekir, ancak değerler başlıktadır.
class A
{
private:
static struct _Shapes {
const std::string RECTANGLE {"rectangle"};
const std::string CIRCLE {"circle"};
} shape;
};
Tek tek üyeleri başlatmak yerine, tüm statik yapı .cpp'de başlatılır:
A::_Shapes A::shape;
Değerlere şununla erişilir:
A::shape.RECTANGLE;
veya - üyeler özel olduklarından ve yalnızca A'dan -
shape.RECTANGLE;
Bu çözümün statik değişkenlerin başlatılma sırasından hala muzdarip olduğunu unutmayın. Bir statik değer başka bir statik değişkeni başlatmak için kullanıldığında, ilki henüz başlatılmamış olabilir.
// file.h
class File {
public:
static struct _Extensions {
const std::string h{ ".h" };
const std::string hpp{ ".hpp" };
const std::string c{ ".c" };
const std::string cpp{ ".cpp" };
} extension;
};
// file.cpp
File::_Extensions File::extension;
// module.cpp
static std::set<std::string> headers{ File::extension.h, File::extension.hpp };
Bu durumda statik değişken başlıkları , bağlayıcı tarafından oluşturulan başlatma sırasına bağlı olarak {""} veya {".h", ".hpp"} içerecektir.
@ Abyss.7 tarafından belirtildiği gibi constexpr
, değişkenin değeri derleme zamanında hesaplanabiliyorsa da kullanabilirsiniz . Ancak, dizelerinizi ile bildirirseniz static constexpr const char*
ve programınız std::string
başka türlü std::string
kullanırsa, böyle bir sabit kullandığınızda yeni bir nesne oluşturulacağı için bir ek yük olacaktır:
class A {
public:
static constexpr const char* STRING = "some value";
};
void foo(const std::string& bar);
int main() {
foo(A::STRING); // a new std::string is constructed and destroyed.
}