Variabel statis kelas dapat dideklarasikan di header tetapi harus didefinisikan dalam file .cpp. Ini karena hanya ada satu contoh variabel statis dan kompilator tidak dapat memutuskan di mana file objek yang dihasilkan untuk meletakkannya sehingga Anda harus membuat keputusan.
Untuk menjaga definisi nilai statis dengan deklarasi di C ++ 11 struktur statis bersarang dapat digunakan. Dalam hal ini anggota statis adalah struktur dan harus didefinisikan dalam file .cpp, tetapi nilainya ada di header.
class A
{
private:
static struct _Shapes {
const std::string RECTANGLE {"rectangle"};
const std::string CIRCLE {"circle"};
} shape;
};
Alih-alih menginisialisasi anggota individu seluruh struktur statis diinisialisasi dalam .cpp:
A::_Shapes A::shape;
Nilai diakses dengan
A::shape.RECTANGLE;
atau - karena anggotanya pribadi dan dimaksudkan untuk digunakan hanya dari A - with
shape.RECTANGLE;
Perhatikan bahwa solusi ini masih menderita dari masalah urutan inisialisasi variabel statis. Ketika nilai statis digunakan untuk menginisialisasi variabel statis lain, yang pertama mungkin belum diinisialisasi.
// 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 };
Dalam hal ini header variabel statis akan berisi {""} atau {".h", ".hpp"}, tergantung pada urutan inisialisasi yang dibuat oleh penghubung.
Seperti disebutkan oleh @ abyss.7 Anda juga dapat menggunakan constexpr
jika nilai variabel dapat dihitung pada waktu kompilasi. Tetapi jika Anda mendeklarasikan string Anda static constexpr const char*
dan program Anda menggunakan std::string
sebaliknya, akan ada overhead karena std::string
objek baru akan dibuat setiap kali Anda menggunakan konstanta seperti itu:
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.
}