ฉันมีเรียน
class foo {
public:
foo();
foo( int );
private:
static const string s;
};
ตำแหน่งที่ดีที่สุดในการเริ่มต้นสตริงs
ในไฟล์ต้นฉบับคืออะไร
ฉันมีเรียน
class foo {
public:
foo();
foo( int );
private:
static const string s;
};
ตำแหน่งที่ดีที่สุดในการเริ่มต้นสตริงs
ในไฟล์ต้นฉบับคืออะไร
คำตอบ:
ที่ใดก็ได้ในหนึ่งหน่วยการคอมไพล์ (โดยปกติคือไฟล์. cpp) จะทำ:
foo.h
class foo {
static const string s; // Can never be initialized here.
static const char* cs; // Same with C strings.
static const int i = 3; // Integral types can be initialized here (*)...
static const int j; // ... OR in cpp.
};
foo.cpp
#include "foo.h"
const string foo::s = "foo string";
const char* foo::cs = "foo C string";
// No definition for i. (*)
const int foo::j = 4;
(*) ตามมาตรฐานคุณต้องกำหนดi
นอกนิยามคลาส (เช่นj
นั้น) ถ้ามันถูกใช้ในโค้ดอื่นที่ไม่ใช่แค่การแสดงออกที่คงที่หนึ่ง ดูความคิดเห็นของ David ด้านล่างเพื่อดูรายละเอียด
i
จะต้องมีการกำหนดไว้เท่านั้นถ้ามันถูกนำมาใช้ที่อื่นกว่าในการแสดงออกอย่างต่อเนื่องหนึ่งใช่มั้ย? ในกรณีนี้คุณไม่สามารถพูดได้ว่ามีข้อผิดพลาดเนื่องจากมีบริบทไม่เพียงพอที่จะแน่ใจ - หรือพูดอย่างเคร่งครัดตัวอย่างข้างต้นนั้นถูกต้องหากไม่มีรหัสอื่น ตอนนี้ฉันขอขอบคุณความคิดเห็นของคุณ (+1) ฉันยังคงเรียนรู้สิ่งต่าง ๆ ด้วยตัวเอง! ดังนั้นฉันจะพยายามและชี้แจงจุดนั้นในคำตอบโปรดแจ้งให้เราทราบว่ามันจะดีกว่า ...
int f() { return 42; } class foo { static const int i = f(); /* Error! */ }
โปรดทราบว่า C ++ 11 อนุญาตให้เรียกฟังก์ชั่น 'constexpr':constexpr int f() { return 42; } class foo { static const int i = f(); /* Ok */ }
สมาชิกแบบคงที่จะต้องเริ่มต้นในหน่วยการแปล. cpp ที่ขอบเขตไฟล์หรือในเนมสเปซที่เหมาะสม:
const string foo::s( "my foo");
ในหน่วยการแปลภายในเนมสเปซเดียวกันโดยปกติจะอยู่ด้านบน:
// foo.h
struct foo
{
static const std::string s;
};
// foo.cpp
const std::string foo::s = "thingadongdong"; // this is where it lives
// bar.h
namespace baz
{
struct bar
{
static const float f;
};
}
// bar.cpp
namespace baz
{
const float bar::f = 3.1415926535;
}
ตั้งแต่ C ++ 17 ตัวระบุแบบอินไลน์ก็ใช้กับตัวแปรเช่นกัน ตอนนี้คุณสามารถกำหนดตัวแปรสมาชิกแบบคงที่ในการกำหนดชั้นเรียน:
#include <string>
class foo {
public:
foo();
foo( int );
private:
inline static const std::string s { "foo" };
};
มีเพียงค่าอินทิกรัล (เช่น, static const int ARRAYSIZE
) เท่านั้นที่ถูกเตรียมใช้งานในไฟล์ส่วนหัวเนื่องจากโดยปกติจะใช้ในส่วนหัวของคลาสเพื่อกำหนดบางอย่างเช่นขนาดของอาร์เรย์ ค่าที่ไม่ครบถ้วนถูกเตรียมใช้งานในไฟล์การนำไปใช้งาน
i
จะต้องกำหนดไว้ใน cpp §9.4.2 / 4 หากสมาชิกข้อมูลแบบคงที่เป็นประเภท const integral หรือการนับ const การประกาศในคำจำกัดความของคลาสสามารถระบุค่าคงที่เริ่มต้นซึ่งจะเป็นนิพจน์ค่าคงที่หนึ่ง (5.19) ในกรณีนั้นสมาชิกสามารถปรากฏเป็นนิพจน์คงที่หนึ่ง สมาชิกจะต้องถูกกำหนดในขอบเขตชื่อพื้นที่ถ้ามันถูกใช้ในโปรแกรมและคำจำกัดความขอบเขตเนมสเปซจะต้องไม่มีการเริ่มต้น