klasy zmienne statyczne mogą być oświadczył w nagłówku, ale musi być zdefiniowane w pliku .cpp. Dzieje się tak dlatego, że może istnieć tylko jedno wystąpienie zmiennej statycznej, a kompilator nie może zdecydować, w którym wygenerowanym pliku obiektowym umieścić, aby zamiast tego podjąć decyzję.
Aby zachować definicję wartości statycznej za pomocą deklaracji w C++ 11 , można użyć zagnieżdżonej struktury statycznej. W tym przypadku element statyczny jest strukturą i musi być zdefiniowany w pliku .cpp, ale wartości znajdują się w nagłówku.
class A
{
private:
static struct _Shapes {
const std::string RECTANGLE {"rectangle"};
const std::string CIRCLE {"circle"};
} shape;
};
Zamiast inicjowania poszczególnych członków całą strukturę statyczną jest inicjowany w .cpp:
A::_Shapes A::shape;
Wartości są dostępne z
A::shape.RECTANGLE;
lub - ponieważ członkowie są prywatne i są przeznaczone do użycia wyłącznie z A - z
shape.RECTANGLE;
Należy zauważyć, że to rozwiązanie nadal cierpi z powodu problemu z inicjalizacją zmiennych statycznych . Gdy wartość statyczna zostanie użyta do zainicjowania innej zmiennej statycznej, , pierwsza może nie zostać zainicjowana, .
// 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 };
W tym przypadku zmienna statyczna nagłówki zawiera zarówno { „”} lub { „.h”, „.hpp”}, w zależności od celu inicjalizacji utworzonego przez łącznik.
Jak wspomniano w @ abyss.7, można również użyć wartości constexpr
, jeśli wartość zmiennej można obliczyć w czasie kompilacji. Ale jeśli deklarują swoje struny static constexpr const char*
i program wykorzystuje std::string
inaczej nie będzie nad głową, ponieważ nowe std::string
obiekt będzie tworzone za każdym razem, gdy używasz takiego Constant:
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.
}
Dzięki za wszystkie wspaniałe odpowiedzi! Niech żyje tak! –
Czy ktoś może mi powiedzieć, jaki jest typ "integralny"? Dziękuję Ci bardzo. –
Typy całkowe odnoszą się do typów reprezentujących liczby całkowite. Zobacz http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fintvar.htm – bleater