ฉันสับสนมากเกี่ยวกับ 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::muninitialized) (Aคือ POD)new A()- ค่าเริ่มต้นAซึ่งเป็นศูนย์เริ่มต้นตั้งแต่ 2 จุดใน[dcl.init] / 8new B- ค่าเริ่มต้นเริ่มต้นBคอมไพเลอร์ gen ctor, (leavsB::muninitialized) (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 จะให้โดยผู้ใช้หากมีการประกาศโดยผู้ใช้และไม่ได้กำหนดค่าเริ่มต้นหรือลบอย่างชัดเจนในการประกาศครั้งแรกลิงก์ )