destructor ได้รับการเรียกโดยอัตโนมัติหรือไม่

คำถามของฉันนั้นง่าย แต่ฉันไม่สามารถค้นหาคำถามได้ทุกที่

ถ้าฉันมีคลาสแบบนี้

class A {
    vector<int> data;
}

เมื่ออินสแตนซ์ของ A ถูกทำลาย data จะถูกทำลายอย่างถูกต้องเช่นกัน หรือฉันควรเขียน destructor สำหรับ A ที่เรียก destructor ของ data โดยพื้นฐานแล้วฉันกังวลว่าหน่วยความจำแบบไดนามิกของเวกเตอร์จะไม่ถูกปล่อยเมื่ออินสแตนซ์ของ A ถูกทำลายหรือไม่ ฉันสงสัยว่าคำตอบคือ data ได้รับการปลดปล่อยอย่างถูกต้อง แต่ฉันไม่ต้องการรู้ว่าฉันผิดอย่างยากลำบาก

นอกจากนี้ หาก A เป็นโครงสร้าง ตัวทำลายสำหรับ data จะถูกเรียกเมื่ออินสแตนซ์ในเครื่องของ A อยู่นอกขอบเขตหรือไม่


person Dunes    schedule 28.02.2012    source แหล่งที่มา
comment
คุณกำลังขาดอัฒภาคหลังจากการประกาศ class A (ซึ่งไม่ใช่การประกาศจริงๆ เนื่องจากขาด... โอ้เอาล่ะ)   -  person Matthieu M.    schedule 28.02.2012


คำตอบ (3)


ใช่ data จะถูกทำลายโดยอัตโนมัติ คุณไม่จำเป็นต้องดำเนินการใดๆ เพื่อให้บรรลุเป้าหมาย vector จะจัดการการล้างหน่วยความจำไดนามิกที่จัดสรรไว้ ตัวทำลายของเวกเตอร์จะถูกเรียกโดยอัตโนมัติเมื่ออินสแตนซ์ของ A ถูกทำลาย

ไม่มีความแตกต่างในการทำงานไม่ว่า A จะเป็น class หรือ struct

person Naveen    schedule 28.02.2012
comment
+1 เพื่อให้ชัดเจน vector จะจัดการการล้างหน่วยความจำไดนามิกที่จัดสรร โดย ไม่ใช่ เพื่อ หากคุณจัดเก็บออบเจ็กต์ที่จัดสรรแบบไดนามิกไว้ในเวกเตอร์ คุณมีหน้าที่รับผิดชอบในการ delete วัตถุเหล่านั้นให้สอดคล้องกัน - person netcoder; 28.02.2012
comment
@netcoder พบว่าความคิดเห็นของคุณทำให้เข้าใจผิดเล็กน้อย คุณสามารถจัดเก็บในเวกเตอร์ พอยน์เตอร์ไปยังวัตถุที่จัดสรรแบบไดนามิก แต่ฉันไม่คิดว่าคุณจะสามารถจัดเก็บวัตถุเองที่จัดสรรแบบไดนามิกในเวกเตอร์ได้ หากคุณประกาศ vector‹ClassA› โดยที่ ClassA เป็นชื่อคลาส เวกเตอร์จะดูแลการทำลายวัตถุ ClassA ที่มีอยู่ แน่นอน หากวัตถุ ClassA ของคุณมีตัวชี้ไปยังวัตถุอื่น มันเป็นความรับผิดชอบของ ClassA ที่จะลบพวกมัน ไม่ใช่ความรับผิดชอบของเวกเตอร์ แต่นั่นเป็นอีกเรื่องหนึ่ง - person Gab是好人; 29.11.2016

ไม่จำเป็น ตัวทำลายข้อมูลของสมาชิกข้อมูลจะถูกเรียกเสมอ

ตัวทำลายล้างที่ชัดเจนคือการจัดการหน่วยความจำแบบแมนนวลที่มีประโยชน์

struct a{
    int* ip;
    a() 
    : ip(new int(5)) 
    { }

    ~a() { delete ip; }
};

ที่กล่าวว่าโดยทั่วไปคุณควรพูดใช้คอนเทนเนอร์ RAII (เช่นตัวชี้อัจฉริยะ) ดังนั้นฉันจึงไม่ค่อยเขียน dtors ที่นั่นโดยส่วนตัว

และข้อยกเว้นคือการประกาศคลาสพื้นฐาน dtor ให้เป็นเสมือน

struct base {
     virtual ~base() {}
};
struct child : public base {
    //base and child destructor automatically called 
}
person 111111    schedule 28.02.2012
comment
+1 สำหรับการปฏิบัติตามหลักการ RAII ที่ดี ความจำเป็นในการเขียน destructors ด้วยตนเองควรจะน้อยลงเรื่อยๆ เมื่อผู้คนเขียนโค้ด C++ ในแบบที่ Stroustrup, Sutter, Meyers และนักคิด C++ ยุคใหม่คนอื่นๆ ตั้งใจให้เราเขียนมัน - person stinky472; 28.02.2012

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

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

person Jason    schedule 28.02.2012