
ให้เราศึกษาความแตกต่างระหว่างตัวสร้างสำเนาและตัวดำเนินการกำหนด
แผนภูมิเปรียบเทียบ
พื้นฐานสำหรับการเปรียบเทียบ | คัดลอกตัวสร้าง | ผู้ประกอบการที่ได้รับมอบหมาย |
---|---|---|
ขั้นพื้นฐาน | ตัวสร้างการคัดลอกเป็นตัวสร้างที่โอเวอร์โหลด | ผู้ประกอบการที่ได้รับมอบหมายเป็นผู้ประกอบการระดับบิต |
ความหมาย | ตัวสร้างสำเนาเริ่มต้นวัตถุใหม่ด้วยวัตถุที่มีอยู่แล้ว | ผู้ประกอบการที่ได้รับมอบหมายกำหนดค่าของวัตถุหนึ่งไปยังวัตถุอื่นทั้งสองซึ่งมีอยู่แล้ว |
วากยสัมพันธ์ | class_name (ต่อ class_name & object_name) { // เนื้อหาของคอนสตรัค } | class_name Ob1, Ob2; Ob2 = Ob1; |
ต้องการเรียก | (1) Copy constructor จะเรียกใช้เมื่อวัตถุใหม่เริ่มต้นด้วยวัตถุที่มีอยู่แล้ว (2) วัตถุผ่านไปยังฟังก์ชั่นเป็นพารามิเตอร์ที่ไม่อ้างอิง (3) วัตถุถูกส่งคืนจากฟังก์ชัน | ผู้ประกอบการที่ได้รับมอบหมายจะถูกเรียกก็ต่อเมื่อการกำหนดวัตถุที่มีอยู่เป็นวัตถุใหม่ |
การจัดสรรหน่วยความจำ | ทั้งวัตถุเป้าหมายและวัตถุเริ่มต้นใช้ตำแหน่งหน่วยความจำที่แตกต่างกัน | ทั้งวัตถุเป้าหมายและวัตถุเริ่มต้นใช้หน่วยความจำที่จัดสรรเดียวกัน |
ค่าเริ่มต้น | หากคุณไม่ได้กำหนดตัวสร้างการคัดลอกใด ๆ ในโปรแกรมคอมไพเลอร์ C ++ จะให้ข้อมูลโดยปริยาย | หากคุณไม่ใช้งานโอเปอเรเตอร์ "=" มากเกินไปจะมีการทำสำเนาบิตอัพ |
ความหมายของตัวสร้างการคัดลอก
"ตัวสร้างการคัดลอก" เป็นรูปแบบของตัว สร้างที่โอเวอร์โหลด ตัวสร้างการคัดลอกเรียกหรือเรียกใช้เพื่อวัตถุประสงค์ในการเริ่มต้นเท่านั้น ตัวสร้างสำเนาเริ่มต้นวัตถุที่สร้างขึ้นใหม่โดยวัตถุอื่นที่มีอยู่ เมื่อตัวสร้างการคัดลอกถูกใช้เพื่อเริ่มต้นวัตถุเป้าหมายที่สร้างขึ้นใหม่ทั้งวัตถุเป้าหมายและวัตถุต้นทางจะใช้ตำแหน่งหน่วยความจำร่วมกัน การเปลี่ยนแปลงที่ทำกับวัตถุต้นฉบับไม่ได้สะท้อนให้เห็นในวัตถุเป้าหมาย รูปแบบทั่วไปของตัวสร้างการคัดลอกคือ
class_ name (class_name & object_name) {. // เนื้อความของตัวสร้างสำเนา } // object_name อ้างถึงวัตถุทางด้านขวามือของการเริ่มต้น
หากโปรแกรมเมอร์ไม่ได้สร้างตัวสร้างสำเนาในโปรแกรม C ++ คอมไพเลอร์จะให้ตัวสร้างสำเนาโดยปริยาย ตัวสร้างสำเนาโดยนัยที่จัดทำโดยคอมไพเลอร์ทำสำเนาสมาชิกที่ชาญฉลาดของวัตถุต้นฉบับ แต่บางครั้งสำเนาสมาชิกที่ฉลาดไม่เพียงพอเนื่องจากวัตถุอาจมีตัวแปรตัวชี้ การคัดลอกตัวแปรพอยน์เตอร์หมายถึงเราคัดลอกที่อยู่ที่เก็บไว้ในตัวแปรพอยน์เตอร์ แต่เราไม่ต้องการคัดลอกที่อยู่ที่เก็บไว้ในตัวแปรพอยน์แทนเราต้องการคัดลอกพอยน์เตอร์ชี้ไปที่ ดังนั้นจึงมีความต้องการ 'ตัวสร้างสำเนา' ที่ชัดเจนในโปรแกรมเพื่อแก้ปัญหาประเภทนี้
ตัวสร้างสำเนาถูกเรียกใช้ในสามเงื่อนไขดังนี้:
- ตัวสร้างการคัดลอกจะเรียกใช้เมื่อวัตถุใหม่เริ่มต้นด้วยวัตถุที่มีอยู่
- วัตถุผ่านไปยังฟังก์ชั่นเป็นพารามิเตอร์ที่ไม่อ้างอิง
- วัตถุถูกส่งคืนจากฟังก์ชัน
ขอให้เราเข้าใจตัวสร้างสำเนาด้วยตัวอย่าง
คัดลอกคลาส {int NUM; สาธารณะ: คัดลอก () {} // เริ่มต้นคัดลอกคอนสตรัค (int a) {// เริ่มต้นนวกรรมิกนวกรรมิก = a; } copy (copy & c) {// คัดลอก constructor num = c.num; } แสดงเป็นโมฆะ () {ศาล << NUM; }}; int main () {คัดลอก A (200); // Object A สร้างและเริ่มต้นคัดลอก B (A); // ตัวสร้างสำเนาเรียกว่า copy C = A; // ตัวสร้างสำเนาเรียกว่า copy D; D = a; // ตัวสร้างสำเนาไม่ถูกเรียกเนื่องจากวัตถุ D ไม่ใช่วัตถุที่สร้างขึ้นใหม่ // เป็นการดำเนินการที่ได้รับมอบหมาย กลับ 0 }
ในรหัสข้างต้นฉันได้ประกาศตัวสร้าง "คัดลอก (คัดลอก & c)" อย่างชัดเจน ตัวสร้างสำเนานี้จะถูกเรียกเมื่อวัตถุ B ถูกเตรียมใช้งานโดยใช้วัตถุ A. ครั้งที่สองจะถูกเรียกเมื่อวัตถุ C จะถูกเริ่มต้นโดยใช้วัตถุ A. เมื่อวัตถุ D ถูกเริ่มต้นโดยใช้วัตถุวัตถุตัวสร้างคัดลอกไม่ได้ถูกเรียกเพราะเมื่อ D จะเริ่มต้น มันมีอยู่แล้วในการดำรงอยู่ไม่ใช่หนึ่งที่สร้างขึ้นใหม่ ดังนั้นที่นี่ผู้ประกอบการที่ได้รับมอบหมายจะถูกเรียก
คำจำกัดความของผู้ประกอบการที่ได้รับมอบหมาย
ตัวดำเนินการกำหนดค่าเป็นตัวดำเนินการกำหนดค่าของ C ++ ตัวดำเนินการ“ =” ถูกใช้เพื่อเรียกใช้ตัวดำเนินการที่ได้รับมอบหมาย มันคัดลอกข้อมูลในวัตถุหนึ่งที่เหมือนกับวัตถุอื่น ผู้ประกอบการที่ได้รับมอบหมายคัดลอกวัตถุหนึ่งไปยังสมาชิกที่ฉลาดอื่น หากคุณไม่โอเวอร์โหลดโอเปอเรเตอร์การดำเนินการมันจะทำการคัดลอกบิทคอยน์ ดังนั้นคุณต้องโอเวอร์โหลดตัวดำเนินการที่ได้รับมอบหมาย
คัดลอกคลาส {int NUM; สาธารณะ: คัดลอก () {} // เริ่มต้นคัดลอกคอนสตรัค (int a) {// เริ่มต้นนวกรรมิกนวกรรมิก = a; } แสดงเป็นโมฆะ () {ศาล << NUM; }}; int main () {คัดลอก A (200); // Object A สร้างและเริ่มต้นคัดลอก B (300); // Object B ถูกสร้างและกำหนดค่าเริ่มต้น B = A; // ผู้ประกอบการที่ได้รับมอบหมายเรียกสำเนา C; C = a; // ผู้ประกอบการที่มอบหมายเรียกคืน 0; }
ในโค้ดด้านบนเมื่อ objectA ถูกกำหนดให้กับวัตถุ B ผู้ประกอบการที่ได้รับมอบหมายจะถูกเรียกเนื่องจากวัตถุทั้งสองมีอยู่แล้ว ในทำนองเดียวกันกรณีเดียวกันคือเมื่อวัตถุ C เริ่มต้นด้วยวัตถุ A
เมื่อดำเนินการกำหนดระดับบิตทั้งสองวัตถุจะแชร์ตำแหน่งหน่วยความจำเดียวกันและการเปลี่ยนแปลงในวัตถุหนึ่งจะสะท้อนให้เห็นในวัตถุอื่น
ความแตกต่างที่สำคัญระหว่างตัวสร้างการคัดลอกและตัวดำเนินการกำหนด
- ตัวสร้างสำเนาเป็นตัวสร้าง overloaded ซึ่งเป็นตัวดำเนินการกำหนดค่าเป็นตัวดำเนินการระดับบิต
- การใช้ตัวสร้างการคัดลอกคุณสามารถเริ่มต้นวัตถุใหม่ด้วยวัตถุที่มีอยู่แล้ว ในทางกลับกันผู้ดำเนินการที่ได้รับมอบหมายจะคัดลอกวัตถุหนึ่งไปยังวัตถุอื่นซึ่งทั้งสองอย่างนั้นมีอยู่แล้ว
- ตัวคัดลอกจะเริ่มต้นเมื่อใดก็ตามที่วัตถุใหม่ถูกเริ่มต้นด้วยวัตถุที่มีอยู่แล้วเมื่อวัตถุถูกส่งผ่านไปยังฟังก์ชั่นเป็นพารามิเตอร์ที่ไม่ refrence หรือเมื่อวัตถุถูกส่งกลับจากฟังก์ชั่น ในทางกลับกันผู้ประกอบการที่ได้รับมอบหมายจะถูกเรียกก็ต่อเมื่อวัตถุจะถูกกำหนดให้กับวัตถุอื่น
- เมื่อวัตถุถูกเริ่มต้นโดยใช้ตัวสร้างการคัดลอกวัตถุเริ่มต้นและวัตถุที่เริ่มต้นใช้ร่วมกันที่ตั้งหน่วยความจำที่แตกต่างกัน ในทางตรงกันข้ามเมื่อวัตถุถูกเริ่มต้นใช้งานโดยผู้ประกอบการที่ได้รับมอบหมายแล้ววัตถุเริ่มต้นและเริ่มต้นใช้ร่วมกันที่ตั้งหน่วยความจำเดียวกัน
- หากคุณไม่ได้กำหนดตัวสร้างสำเนาอย่างชัดเจนคอมไพเลอร์จะให้หนึ่ง ในทางกลับกันหากคุณไม่ได้โหลดโอเปอเรเตอร์การกำหนดจำนวนมากเกินไปการดำเนินการคัดลอกบิทจะถูกดำเนินการ
สรุป:
ตัวสร้างการคัดลอกที่ดีที่สุดสำหรับการคัดลอกวัตถุหนึ่งไปยังอีกเมื่อวัตถุประกอบด้วยตัวชี้ดิบ