เหตุผลก็คือถ้าคลาสไม่มีคอนสตรัคเตอร์ที่ผู้ใช้กำหนดเองก็สามารถเป็น POD ได้และคลาส POD จะไม่ถูกกำหนดค่าเริ่มต้นตามค่าเริ่มต้น ดังนั้นหากคุณประกาศวัตถุ const ของ POD ซึ่งไม่ได้กำหนดค่าเริ่มต้นจะใช้อะไร? ดังนั้นฉันคิดว่า Standard บังคับใช้กฎนี้เพื่อให้ออบเจ็กต์สามารถใช้ประโยชน์ได้จริง
struct POD
{
int i;
};
POD p1;
p1.i = 10;
POD p2 = POD();
const POD p3 = POD();
const POD p4;
แต่ถ้าคุณทำให้ชั้นเรียนเป็นแบบไม่ใช่ POD:
struct nonPOD_A
{
nonPOD_A() {}
};
nonPOD_A a1;
const nonPOD_A a2;
สังเกตความแตกต่างระหว่าง POD และ non-POD
ตัวสร้างที่ผู้ใช้กำหนดเป็นวิธีหนึ่งที่จะทำให้คลาสไม่ใช่ POD มีหลายวิธีที่คุณสามารถทำได้
struct nonPOD_B
{
virtual void f() {}
};
nonPOD_B b1;
const nonPOD_B b2;
สังเกตว่า nonPOD_B ไม่ได้กำหนดคอนสตรัคเตอร์ที่ผู้ใช้กำหนดเอง รวบรวมมัน. มันจะรวบรวม:
และแสดงความคิดเห็นเกี่ยวกับฟังก์ชันเสมือนจากนั้นแสดงข้อผิดพลาดตามที่คาดไว้:
ฉันคิดว่าคุณเข้าใจข้อความนี้ผิด ก่อนอื่นบอกว่าสิ่งนี้ (§8.5 / 9):
หากไม่ได้ระบุตัวเริ่มต้นสำหรับอ็อบเจ็กต์และอ็อบเจ็กต์เป็นประเภทคลาสที่ไม่ใช่ POD (หรืออาร์เรย์ของอ็อบเจ็กต์) (หรืออาร์เรย์) อ็อบเจ็กต์นั้นจะถูกกำหนดค่าเริ่มต้นโดยปริยาย [... ]
มันพูดถึงคลาสที่ไม่ใช่ POD ซึ่งอาจเป็นประเภทที่ผ่านการรับรอง CV นั่นคืออ็อบเจ็กต์ที่ไม่ใช่ POD จะถูกกำหนดค่าเริ่มต้นโดยปริยายหากไม่มีการระบุตัวเริ่มต้น และค่าเริ่มต้นเริ่มต้นคืออะไร? สำหรับ non-POD ข้อกำหนดระบุว่า (§8.5 / 5)
ในการกำหนดค่าเริ่มต้นวัตถุประเภท T หมายถึง:
- ถ้า T เป็นประเภทคลาสที่ไม่ใช่ POD (ข้อ 9) ตัวสร้างเริ่มต้นสำหรับ T จะถูกเรียก (และการกำหนดค่าเริ่มต้นจะมีรูปแบบไม่ถูกต้องหาก T ไม่มีตัวสร้างเริ่มต้นที่สามารถเข้าถึงได้)
เพียงแค่พูดถึงตัวสร้างเริ่มต้นของ T ไม่ว่าผู้ใช้กำหนดเองหรือสร้างโดยคอมไพเลอร์นั้นไม่เกี่ยวข้องกัน
หากคุณเข้าใจสิ่งนี้แล้วให้เข้าใจว่าข้อกำหนดต่อไปพูดว่าอย่างไร ((§8.5 / 9)
[... ]; ถ้าออบเจ็กต์เป็นประเภทที่มีคุณสมบัติของ const ประเภทคลาสที่อยู่ภายใต้จะต้องมีตัวสร้างเริ่มต้นที่ผู้ใช้ประกาศ
ดังนั้นข้อความนี้จึงหมายความว่าโปรแกรมจะมีรูปแบบไม่ถูกต้องหากวัตถุเป็นประเภท POD ที่มีคุณสมบัติเหมาะสมและไม่มีการระบุตัวเริ่มต้น (เนื่องจาก POD ไม่ใช่ค่าเริ่มต้นเริ่มต้น):
POD p1;
const POD p2;
อย่างไรก็ตามสิ่งนี้คอมไพล์ได้ดีเนื่องจากไม่ใช่ POD และสามารถกำหนดค่าเริ่มต้นได้
a
แต่ gcc-4.3.4 ยอมรับแม้ในขณะที่คุณทำ (ดูideone.com/uHvFS )