C ++ ตำแหน่งที่จะเริ่มต้นคงที่ const


129

ฉันมีเรียน

class foo {
public:
   foo();
   foo( int );
private:
   static const string s;
};

ตำแหน่งที่ดีที่สุดในการเริ่มต้นสตริงsในไฟล์ต้นฉบับคืออะไร

คำตอบ:


178

ที่ใดก็ได้ในหนึ่งหน่วยการคอมไพล์ (โดยปกติคือไฟล์. 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 ด้านล่างเพื่อดูรายละเอียด


27
ฉันอัปโหลดแล้ว แต่หลังจากตรวจสอบมาตรฐานมีข้อผิดพลาดในรหัสของคุณ: iจะต้องกำหนดไว้ใน cpp §9.4.2 / 4 หากสมาชิกข้อมูลแบบคงที่เป็นประเภท const integral หรือการนับ const การประกาศในคำจำกัดความของคลาสสามารถระบุค่าคงที่เริ่มต้นซึ่งจะเป็นนิพจน์ค่าคงที่หนึ่ง (5.19) ในกรณีนั้นสมาชิกสามารถปรากฏเป็นนิพจน์คงที่หนึ่ง สมาชิกจะต้องถูกกำหนดในขอบเขตชื่อพื้นที่ถ้ามันถูกใช้ในโปรแกรมและคำจำกัดความขอบเขตเนมสเปซจะต้องไม่มีการเริ่มต้น
David Rodríguez - dribeas

3
ขึ้นอยู่กับคำพูดของคุณจากมาตรฐานที่ดูเหมือนว่าiจะต้องมีการกำหนดไว้เท่านั้นถ้ามันถูกนำมาใช้ที่อื่นกว่าในการแสดงออกอย่างต่อเนื่องหนึ่งใช่มั้ย? ในกรณีนี้คุณไม่สามารถพูดได้ว่ามีข้อผิดพลาดเนื่องจากมีบริบทไม่เพียงพอที่จะแน่ใจ - หรือพูดอย่างเคร่งครัดตัวอย่างข้างต้นนั้นถูกต้องหากไม่มีรหัสอื่น ตอนนี้ฉันขอขอบคุณความคิดเห็นของคุณ (+1) ฉันยังคงเรียนรู้สิ่งต่าง ๆ ด้วยตัวเอง! ดังนั้นฉันจะพยายามและชี้แจงจุดนั้นในคำตอบโปรดแจ้งให้เราทราบว่ามันจะดีกว่า ...
squelart

@squelart ขออภัยถ้าฉันฟังดูเป็นใบ้ แต่ตัวอย่างของคำสั่งอื่นนอกเหนือจากนิพจน์ค่าคงที่หนึ่งจะเป็นอย่างไร
Saksham

3
@ Saksham ตัวอย่างเช่นการเรียกฟังก์ชั่นเช่น: 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 */ }
squelart

@squelart ฉันอ่านข้อความที่ต้องให้คำจำกัดความหากสมาชิกใช้เลย - ถ้อยคำในมาตรฐานไม่ได้จำกัดความต้องการของการแสดงออกที่คงที่
VladLosev

12

สมาชิกแบบคงที่จะต้องเริ่มต้นในหน่วยการแปล. cpp ที่ขอบเขตไฟล์หรือในเนมสเปซที่เหมาะสม:

const string foo::s( "my foo");

11

ในหน่วยการแปลภายในเนมสเปซเดียวกันโดยปกติจะอยู่ด้านบน:

// 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;
}

8

ตั้งแต่ C ++ 17 ตัวระบุแบบอินไลน์ก็ใช้กับตัวแปรเช่นกัน ตอนนี้คุณสามารถกำหนดตัวแปรสมาชิกแบบคงที่ในการกำหนดชั้นเรียน:

#include <string>

class foo {
public:
   foo();
   foo( int );
private:
   inline static const std::string s { "foo" };
};

1

มีเพียงค่าอินทิกรัล (เช่น, static const int ARRAYSIZE) เท่านั้นที่ถูกเตรียมใช้งานในไฟล์ส่วนหัวเนื่องจากโดยปกติจะใช้ในส่วนหัวของคลาสเพื่อกำหนดบางอย่างเช่นขนาดของอาร์เรย์ ค่าที่ไม่ครบถ้วนถูกเตรียมใช้งานในไฟล์การนำไปใช้งาน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.