กฎสามข้อเป็นหนึ่งในกฎของ C ++ ภายใต้กฎทั่วไปสำหรับการสร้าง safecode ข้อยกเว้น กฎเหล่านี้กำหนดวิธีการใช้สมาชิกเริ่มต้นของชั้นเรียนสำหรับการฝึกปฏิบัติที่ไม่มีข้อยกเว้น
กฎสามข้อเรียกอีกอย่างว่ากฎของสามกลุ่มใหญ่หรือสามกลุ่มใหญ่ และกำหนดสำหรับกลุ่มที่ หากชั้นเรียนกำหนดหนึ่งในสามข้อที่กล่าวถึง ก็น่าจะให้คำจำกัดความทั้งสามอย่างชัดเจน -
- ตัวทำลาย
- คัดลอกคอนสตรัคเตอร์
- คัดลอกตัวสร้างการกำหนด
ทั้งสามนี้เป็นฟังก์ชันสมาชิกพิเศษของคลาส หากไม่มีการกำหนดอย่างชัดเจนโดยโปรแกรมเมอร์ คอมไพเลอร์จะจัดเตรียมเวอร์ชันโดยปริยาย หากข้อใดข้อหนึ่งข้างต้นถูกกำหนดไว้อย่างชัดแจ้ง นั่นหมายความว่าเวอร์ชันโดยนัยสำหรับอีกสองเวอร์ชันต้องไม่เหมาะสมและต้องกำหนดใหม่
สิ่งนี้เกิดขึ้นเนื่องจากการสร้างโดยนัยของตัวสร้างและตัวดำเนินการมอบหมายให้คัดลอกข้อมูลสมาชิก เราต้องการการคัดลอกแบบลึกเมื่อคลาสมีพอยน์เตอร์ที่ชี้ไปยังทรัพยากรที่จัดสรรแบบไดนามิก
destructors เริ่มต้นลบวัตถุที่ไม่ได้ใช้ เมื่อไม่มีการกำหนดตัวสร้างการคัดลอก destructor จะทำงานสองครั้ง หนึ่งครั้งสำหรับอ็อบเจ็กต์ที่มีการคัดลอก และตัวที่สองสำหรับอ็อบเจ็กต์ที่สมาชิกข้อมูลถูกคัดลอก เพื่อหลีกเลี่ยงสิ่งนี้ จำเป็นต้องมีคำจำกัดความที่ชัดเจน
ให้เราเข้าใจด้วยตัวอย่างที่ไม่มีตัวสร้างการคัดลอกและตัวดำเนินการมอบหมายการคัดลอก แต่มีตัวทำลาย -
ตัวอย่าง
#include <stdio.h> class Numbers{ private: int num; int* ptr; public: Numbers( int n, int* p ) //copy constructor{ num =n ; ptr = new int[ num ]; } ~Numbers() //destructor{ delete ptr; ptr = NULL; } }; int main(){ int arr[ 4 ] = { 11, 22, 33, 44 }; Numbers Num1( 4, arr ); // this creates problem Numbers Num2( Num1 ); return 0; }
ผลลัพธ์
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001f46c20 *** Aborted
-
สิ่งนี้เกิดขึ้นเพราะตัวทำลายล้างถูกเรียกสองครั้งเมื่อโปรแกรมอยู่นอกขอบเขต การลบ Num1 ครั้งแรกแล้วสำหรับ Num2 ตัวสร้างการคัดลอกเริ่มต้นสร้างสำเนาของตัวชี้ ptr แต่ไม่ได้จัดสรรหน่วยความจำสำหรับมัน ดังนั้น เมื่อลบ Num1 ptrs ออกจะทำให้โปรแกรมหยุดทำงาน