คำสั่งเริ่มต้นรายการประเมินผลตัวสร้าง


252

ฉันมีตัวสร้างที่ใช้อาร์กิวเมนต์บางอย่าง ฉันสันนิษฐานว่าพวกเขาถูกสร้างขึ้นตามลำดับที่ระบุไว้ แต่ในกรณีหนึ่งดูเหมือนว่าพวกเขากำลังสร้างในสิ่งที่ตรงกันข้ามทำให้เกิดการยกเลิก เมื่อฉันย้อนกลับข้อโต้แย้งโปรแกรมหยุดยกเลิก นี่คือตัวอย่างของไวยากรณ์ที่ฉันใช้ สิ่งนี้คือ a_ ต้องเริ่มต้นก่อน b_ ในกรณีนี้ คุณสามารถรับประกันลำดับของการก่อสร้างได้หรือไม่?

เช่น

class A
{
  public:
    A(OtherClass o, string x, int y) :
      a_(o), b_(a_, x, y) { }

    OtherClass a_;
    AnotherClass b_;
};

6
คุณบอกว่าคุณกำลังถามเกี่ยวกับข้อโต้แย้งคอนสตรัค แต่พวกเขากำลังประเมินก่อนที่คุณจะถึงคอนสตรัคเตอร์และพวกเขากำลังประเมินตามลำดับที่ไม่เจาะจงกำหนดคอมไพเลอร์ แต่คุณกำลังถามเกี่ยวกับลำดับของรายการเริ่มต้นดังนั้นฉันจึงเปลี่ยนชื่อคำถามสำหรับคุณ
ร็อบเคนเนดี

คำตอบ:


278

มันขึ้นอยู่กับคำสั่งของการประกาศตัวแปรสมาชิกในชั้นเรียน ดังนั้นa_จะเป็นคนแรกจากนั้นb_จะเป็นคนที่สองในตัวอย่างของคุณ


22
ในความเป็นจริงคอมไพเลอร์ที่ดีจะเตือนถ้าคุณมีคำสั่งที่แตกต่างกันในการประกาศเมื่อเทียบกับรายการเริ่มต้นของตัวสร้าง ตัวอย่างเช่นดูเป็น-Wreordergcc
Greg Hewgill

236
เหตุผลที่พวกเขาถูกสร้างขึ้นในคำสั่งประกาศสมาชิกและไม่ได้อยู่ในคำสั่งในการสร้างคือว่าหนึ่งอาจมีหลายตัวก่อสร้าง แต่มีเพียงหนึ่ง destructor และผู้ทำลายล้างทำลายสมาชิกตามลำดับการก่อสร้าง
AProgrammer

3
เราหมายถึง ... คำสั่งย้อนกลับของการประกาศ ไม่ใช่ "การก่อสร้าง" ผู้ทำลายไม่สามารถมองเข้าไปในตัวสร้างเพื่อที่จะรู้ได้
Conrad B

196

เพื่ออ้างอิงมาตรฐานสำหรับการชี้แจง:

12.6.2.5

การเริ่มต้นจะดำเนินการตามลำดับต่อไปนี้:

...

  • จากนั้นสมาชิกข้อมูลที่ไม่คงที่จะเริ่มต้นได้ตามลำดับที่ประกาศไว้ในคำจำกัดความของคลาส (อีกครั้งโดยไม่คำนึงถึงลำดับของ mem-initializers)

...


18

การอ้างอิงมาตรฐานสำหรับสิ่งนี้ปรากฏเป็น 12.6.2 ส่วน 13.3:

(13.3) - จากนั้นสมาชิกข้อมูลที่ไม่คงที่จะเริ่มต้นในลำดับที่พวกเขาถูกประกาศในคำจำกัดความของคลาส (อีกครั้งโดยไม่คำนึงถึงคำสั่งของ mem-initializers)

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