ตัวแปรสแตติกคลาสสามารถประกาศในส่วนหัว แต่ต้องกำหนดไว้ในไฟล์. cpp นี่เป็นเพราะอาจมีเพียงหนึ่งอินสแตนซ์ของตัวแปรแบบคงที่และคอมไพเลอร์ไม่สามารถตัดสินใจได้ว่าจะสร้างไฟล์วัตถุใดเพื่อให้คุณต้องทำการตัดสินใจแทน
เพื่อให้คำจำกัดความของค่าคงที่ด้วยการประกาศใน C ++ 11 โครงสร้างแบบคงที่ซ้อนสามารถใช้ ในกรณีนี้สมาชิกแบบสแตติกเป็นโครงสร้างและจะต้องกำหนดไว้ในไฟล์. cpp แต่ค่าจะอยู่ในส่วนหัว
class A
{
private:
static struct _Shapes {
const std::string RECTANGLE {"rectangle"};
const std::string CIRCLE {"circle"};
} shape;
};
แทนที่จะเริ่มสมาชิกแต่ละรายโครงสร้างแบบคงที่ทั้งหมดจะเริ่มต้นใน. cpp:
A::_Shapes A::shape;
ค่าที่เข้าถึงได้ด้วย
A::shape.RECTANGLE;
หรือ - เนื่องจากสมาชิกเป็นแบบส่วนตัวและมีความตั้งใจที่จะใช้จาก A - with เท่านั้น
shape.RECTANGLE;
โปรดทราบว่าการแก้ปัญหานี้ยังคงได้รับความทุกข์ทรมานจากปัญหาของลำดับการเริ่มต้นของตัวแปรคงที่ เมื่อค่าคงที่ถูกใช้เพื่อเริ่มต้นตัวแปรคงที่อื่นตัวแปรตัวแรกอาจยังไม่เริ่มต้นได้
// 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 };
ในกรณีนี้ตัวแปรคงที่ ส่วนหัวของจะมี {""} หรือ {".h", ".hpp"} ขึ้นอยู่กับลำดับของการเริ่มต้นที่สร้างขึ้นโดย linker
ตามที่กล่าวไว้โดย @ abyss.7 คุณสามารถใช้constexpr
หากค่าของตัวแปรสามารถคำนวณได้ในเวลารวบรวม แต่ถ้าคุณประกาศสตริงของคุณด้วยstatic constexpr const char*
และโปรแกรมของคุณใช้เป็นstd::string
อย่างอื่นจะมีค่าใช้จ่ายเพราะstd::string
วัตถุใหม่จะถูกสร้างขึ้นทุกครั้งที่คุณใช้ค่าคงที่:
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.
}