ฉันสับสนมากเกี่ยวกับ value- & default- & zero-initialization และโดยเฉพาะอย่างยิ่งเมื่อพวกเขาเริ่มใช้มาตรฐานC ++ 03และC ++ 11ที่แตกต่างกัน(และC ++ 14 )
ฉันกำลังอ้างถึงและพยายามขยายคำตอบที่ดีจริงๆValue- / Default- / Zero- Init C ++ 98และC ++ 03ที่นี่เพื่อให้กว้างขึ้นเนื่องจากจะช่วยผู้ใช้จำนวนมากหากมีใครช่วยกรอก จำเป็นต้องมีช่องว่างเพื่อให้มีภาพรวมที่ดีว่าจะเกิดอะไรขึ้นเมื่อใด
ข้อมูลเชิงลึกทั้งหมดโดยตัวอย่างโดยสรุป:
บางครั้งหน่วยความจำที่ส่งคืนโดยตัวดำเนินการใหม่จะถูกเตรียมใช้งานและบางครั้งก็ไม่ขึ้นอยู่กับว่าประเภทที่คุณกำลังสร้างขึ้นใหม่นั้นเป็นPOD (ข้อมูลเก่าธรรมดา)หรือถ้าเป็นคลาสที่มีสมาชิก POD และใช้ ตัวสร้างเริ่มต้นที่สร้างโดยคอมไพเลอร์
- ในC ++ 1998มีการกำหนดค่าเริ่มต้น 2 ประเภท: zero-และdefault-initialization
- ในC ++ 2003เป็นประเภทที่ 3 ของการเริ่มต้นการกำหนดค่าเริ่มต้นถูกเพิ่ม
- ในC ++ 2011 / C ++ 2014มีการเพิ่มเฉพาะรายการเริ่มต้นและกฎสำหรับค่า- / ค่าเริ่มต้น / ศูนย์ - เริ่มต้นเปลี่ยนแปลงเล็กน้อย
สมมติ:
struct A { int m; };
struct B { ~B(); int m; };
struct C { C() : m(){}; ~C(); int m; };
struct D { D(){}; int m; };
struct E { E() = default; int m;}; /** only possible in c++11/14 */
struct F {F(); int m;}; F::F() = default; /** only possible in c++11/14 */
ในคอมไพเลอร์ C ++ 98 สิ่งต่อไปนี้ควรเกิดขึ้น :
new A
- ค่าไม่แน่นอน (A
คือ POD)new A()
- เริ่มต้นเป็นศูนย์new B
- โครงสร้างเริ่มต้น (B::m
ไม่ได้กำหนดค่าเริ่มต้นB
ไม่ใช่ POD)new B()
- โครงสร้างเริ่มต้น (B::m
ไม่ได้เริ่มต้น)new C
- โครงสร้างเริ่มต้น (C::m
เป็นศูนย์เริ่มต้นC
ไม่ใช่ POD)new C()
- โครงสร้างเริ่มต้น (C::m
เป็นศูนย์เริ่มต้น)new D
- โครงสร้างเริ่มต้น (D::m
ไม่ได้กำหนดค่าเริ่มต้นD
ไม่ใช่ POD)new D()
- โครงสร้างเริ่มต้น? (D::m
ไม่ได้กำหนดค่าเริ่มต้น)
ในคอมไพเลอร์ที่สอดคล้องกับ C ++ 03 สิ่งต่างๆควรเป็นดังนี้:
new A
- ค่าไม่แน่นอน (A
คือ POD)new A()
- ค่าเริ่มต้นA
ซึ่งเป็นศูนย์เริ่มต้นเนื่องจากเป็น PODnew B
- ค่าเริ่มต้นเริ่มต้น (ปล่อยให้B::m
ไม่ได้เริ่มต้นB
ไม่ใช่ POD)new B()
- ค่าเริ่มต้นB
ซึ่งเป็นศูนย์เริ่มต้นฟิลด์ทั้งหมดเนื่องจาก ctor เริ่มต้นเป็นคอมไพเลอร์ที่สร้างขึ้นเมื่อเทียบกับที่ผู้ใช้กำหนดnew C
- default-initializesC
ซึ่งเรียก ctor เริ่มต้น (C::m
เป็นศูนย์เริ่มต้นC
ไม่ใช่ POD)new C()
- ค่าเริ่มต้นC
ซึ่งเรียก ctor เริ่มต้น (C::m
เป็นศูนย์เริ่มต้น)new D
- โครงสร้างเริ่มต้น (D::m
ไม่ได้กำหนดค่าเริ่มต้นD
ไม่ใช่ POD)new D()
- ค่าเริ่มต้น D? ซึ่งเรียก ctor เริ่มต้น (D::m
ไม่ได้เริ่มต้น)
ค่าตัวเอียงและ? เป็นความไม่แน่นอนโปรดช่วยแก้ไข :-)
ในคอมไพเลอร์ที่สอดคล้องกับ C ++ 11 สิ่งต่างๆควรเป็นดังนี้:
??? (โปรดช่วยถ้าฉันเริ่มที่นี่มันจะผิดไป)
ในคอมไพเลอร์ที่สอดคล้องกับ C ++ 14 สิ่งต่างๆควรทำงานดังนี้: ??? (โปรดช่วยถ้าฉันเริ่มที่นี่มันจะผิดพลาด) (ร่างตามคำตอบ)
new A
- ค่าเริ่มต้นเริ่มต้นA
คอมไพเลอร์ gen ctor, (leavsA::m
uninitialized) (A
คือ POD)new A()
- ค่าเริ่มต้นA
ซึ่งเป็นศูนย์เริ่มต้นตั้งแต่ 2 จุดใน[dcl.init] / 8new B
- ค่าเริ่มต้นเริ่มต้นB
คอมไพเลอร์ gen ctor, (leavsB::m
uninitialized) (B
ไม่ใช่ POD)new B()
- ค่าเริ่มต้นB
ซึ่งเป็นศูนย์เริ่มต้นฟิลด์ทั้งหมดเนื่องจาก ctor เริ่มต้นเป็นคอมไพเลอร์ที่สร้างขึ้นเมื่อเทียบกับที่ผู้ใช้กำหนดnew C
- default-initializesC
ซึ่งเรียก ctor เริ่มต้น (C::m
เป็นศูนย์เริ่มต้นC
ไม่ใช่ POD)new C()
- ค่าเริ่มต้นC
ซึ่งเรียก ctor เริ่มต้น (C::m
เป็นศูนย์เริ่มต้น)new D
- ค่าเริ่มต้นเริ่มต้นD
(D::m
ไม่ได้กำหนดค่าเริ่มต้นD
ไม่ใช่ POD)new D()
- ค่าเริ่มต้นD
ซึ่งเรียก ctor เริ่มต้น (D::m
ไม่ได้กำหนดค่าเริ่มต้น)new E
- default-initializesE
ซึ่งเรียกคอมพ์ gen. ctor. (E::m
ไม่ได้กำหนดค่าเริ่มต้น E ไม่ใช่ POD)new E()
- ค่าเริ่มต้นE
ซึ่งเป็นศูนย์เริ่มต้นE
ตั้งแต่ 2 จุดใน[dcl.init] / 8 )new F
- default-initializesF
ซึ่งเรียกคอมพ์ gen. ctor. (F::m
ไม่ได้กำหนดF
ค่าเริ่มต้นไม่ใช่ POD)new F()
- ค่าเริ่มต้นF
ซึ่งเริ่มต้นโดยค่าเริ่มต้นF
ตั้งแต่ 1. จุดใน[dcl.init] / 8 (F
ฟังก์ชัน ctor จะให้โดยผู้ใช้หากมีการประกาศโดยผู้ใช้และไม่ได้กำหนดค่าเริ่มต้นหรือลบอย่างชัดเจนในการประกาศครั้งแรกลิงก์ )