แนะนำ, 2024

ตัวเลือกของบรรณาธิการ

ความแตกต่างระหว่าง Copy Constructor และ Operator Assignment ใน C ++

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

ให้เราศึกษาความแตกต่างระหว่างตัวสร้างสำเนาและตัวดำเนินการกำหนด

แผนภูมิเปรียบเทียบ

พื้นฐานสำหรับการเปรียบเทียบคัดลอกตัวสร้างผู้ประกอบการที่ได้รับมอบหมาย
ขั้นพื้นฐานตัวสร้างการคัดลอกเป็นตัวสร้างที่โอเวอร์โหลดผู้ประกอบการที่ได้รับมอบหมายเป็นผู้ประกอบการระดับบิต
ความหมายตัวสร้างสำเนาเริ่มต้นวัตถุใหม่ด้วยวัตถุที่มีอยู่แล้วผู้ประกอบการที่ได้รับมอบหมายกำหนดค่าของวัตถุหนึ่งไปยังวัตถุอื่นทั้งสองซึ่งมีอยู่แล้ว
วากยสัมพันธ์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

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

ความแตกต่างที่สำคัญระหว่างตัวสร้างการคัดลอกและตัวดำเนินการกำหนด

  1. ตัวสร้างสำเนาเป็นตัวสร้าง overloaded ซึ่งเป็นตัวดำเนินการกำหนดค่าเป็นตัวดำเนินการระดับบิต
  2. การใช้ตัวสร้างการคัดลอกคุณสามารถเริ่มต้นวัตถุใหม่ด้วยวัตถุที่มีอยู่แล้ว ในทางกลับกันผู้ดำเนินการที่ได้รับมอบหมายจะคัดลอกวัตถุหนึ่งไปยังวัตถุอื่นซึ่งทั้งสองอย่างนั้นมีอยู่แล้ว
  3. ตัวคัดลอกจะเริ่มต้นเมื่อใดก็ตามที่วัตถุใหม่ถูกเริ่มต้นด้วยวัตถุที่มีอยู่แล้วเมื่อวัตถุถูกส่งผ่านไปยังฟังก์ชั่นเป็นพารามิเตอร์ที่ไม่ refrence หรือเมื่อวัตถุถูกส่งกลับจากฟังก์ชั่น ในทางกลับกันผู้ประกอบการที่ได้รับมอบหมายจะถูกเรียกก็ต่อเมื่อวัตถุจะถูกกำหนดให้กับวัตถุอื่น
  4. เมื่อวัตถุถูกเริ่มต้นโดยใช้ตัวสร้างการคัดลอกวัตถุเริ่มต้นและวัตถุที่เริ่มต้นใช้ร่วมกันที่ตั้งหน่วยความจำที่แตกต่างกัน ในทางตรงกันข้ามเมื่อวัตถุถูกเริ่มต้นใช้งานโดยผู้ประกอบการที่ได้รับมอบหมายแล้ววัตถุเริ่มต้นและเริ่มต้นใช้ร่วมกันที่ตั้งหน่วยความจำเดียวกัน
  5. หากคุณไม่ได้กำหนดตัวสร้างสำเนาอย่างชัดเจนคอมไพเลอร์จะให้หนึ่ง ในทางกลับกันหากคุณไม่ได้โหลดโอเปอเรเตอร์การกำหนดจำนวนมากเกินไปการดำเนินการคัดลอกบิทจะถูกดำเนินการ

สรุป:

ตัวสร้างการคัดลอกที่ดีที่สุดสำหรับการคัดลอกวัตถุหนึ่งไปยังอีกเมื่อวัตถุประกอบด้วยตัวชี้ดิบ

Top