เกิดอะไรขึ้น
เมื่อคุณเขียนT t;
คุณกำลังสร้างวัตถุของการพิมพ์ที่T
มีระยะเวลาการจัดเก็บข้อมูลโดยอัตโนมัติ ระบบจะล้างข้อมูลโดยอัตโนมัติเมื่ออยู่นอกขอบเขต
เมื่อคุณเขียนnew T()
คุณกำลังสร้างวัตถุของการพิมพ์ที่T
มีระยะเวลาการจัดเก็บข้อมูลแบบไดนามิก มันจะไม่ถูกล้างโดยอัตโนมัติ
คุณต้องส่งตัวชี้ไปที่ตัวชี้delete
เพื่อทำความสะอาด:
อย่างไรก็ตามตัวอย่างที่สองของคุณแย่กว่านั้น: คุณกำลังยกเลิกการอ้างอิงตัวชี้และสร้างสำเนาของวัตถุ ด้วยวิธีนี้คุณจะสูญเสียตัวชี้ไปยังวัตถุที่สร้างด้วยnew
ดังนั้นคุณจึงไม่สามารถลบได้แม้ว่าคุณจะต้องการก็ตาม!
สิ่งที่คุณควรทำ
คุณควรเลือกระยะเวลาการจัดเก็บอัตโนมัติ ต้องการวัตถุใหม่เพียงเขียน:
A a; // a new object of type A
B b; // a new object of type B
หากคุณต้องการระยะเวลาการจัดเก็บแบบไดนามิกให้จัดเก็บตัวชี้ไปยังวัตถุที่จัดสรรไว้ในออบเจ็กต์ระยะเวลาการจัดเก็บอัตโนมัติที่ลบออกโดยอัตโนมัติ
template <typename T>
class automatic_pointer {
public:
automatic_pointer(T* pointer) : pointer(pointer) {}
// destructor: gets called upon cleanup
// in this case, we want to use delete
~automatic_pointer() { delete pointer; }
// emulate pointers!
// with this we can write *p
T& operator*() const { return *pointer; }
// and with this we can write p->f()
T* operator->() const { return pointer; }
private:
T* pointer;
// for this example, I'll just forbid copies
// a smarter class could deal with this some other way
automatic_pointer(automatic_pointer const&);
automatic_pointer& operator=(automatic_pointer const&);
};
automatic_pointer<A> a(new A()); // acts like a pointer, but deletes automatically
automatic_pointer<B> b(new B()); // acts like a pointer, but deletes automatically
นี่เป็นสำนวนทั่วไปที่ใช้ชื่อ RAII ที่ไม่ค่อยมีคำอธิบาย ( Resource Acquisition Is Initialization ) เมื่อคุณได้รับทรัพยากรที่ต้องการการล้างข้อมูลคุณจะติดไว้ในวัตถุที่มีระยะเวลาจัดเก็บอัตโนมัติดังนั้นคุณจึงไม่ต้องกังวลกับการล้าง สิ่งนี้ใช้ได้กับทรัพยากรใด ๆ ไม่ว่าจะเป็นหน่วยความจำไฟล์ที่เปิดการเชื่อมต่อเครือข่ายหรืออะไรก็ตามที่คุณต้องการ
automatic_pointer
สิ่งนี้มีอยู่แล้วในรูปแบบต่างๆฉันเพิ่งให้มันเป็นตัวอย่าง std::unique_ptr
ชั้นที่คล้ายกันมากที่มีอยู่ในห้องสมุดมาตรฐานที่เรียกว่า
นอกจากนี้ยังมีชื่อเก่า (ก่อน C ++ 11) auto_ptr
แต่ตอนนี้เลิกใช้แล้วเพราะมีพฤติกรรมการคัดลอกที่แปลกประหลาด
จากนั้นก็มีตัวอย่างที่ชาญฉลาดกว่าเช่นstd::shared_ptr
ที่ช่วยให้ตัวชี้หลายตัวไปยังวัตถุเดียวกันและทำความสะอาดเมื่อตัวชี้ตัวสุดท้ายถูกทำลายเท่านั้น