Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

Array Members ใน Struct/Class ถูก Deep Copy อัตโนมัติใน C++

หัวใจสำคัญ

ใน C/C++ เมื่อ Assign Struct/Class Variable ให้กับอีกตัวหนึ่งประเภทเดียวกัน Array Members จะถูก Deep Copy อัตโนมัติ โดย Compiler (ไม่ใช่ Shallow Copy)

ตัวอย่างยืนยัน

#include <iostream>
#include <cstring>
using namespace std;

struct Test {
    char str[20];
};

int main() {
    Test st1, st2;
    strcpy(st1.str, "Tutorial Point");
    st2 = st1;           // Assignment - Compiler ทำ Deep Copy Array

    st1.str[0] = 'X';    // แก้ไข st1
    st1.str[1] = 'Y';

    cout << "st1's str = " << st1.str << endl;  // XYtorial Point
    cout << "st2's str = " << st2.str << endl;  // Tutorial Point (ไม่เปลี่ยน!)

    return 0;
}

ผลลัพธ์

st1's str = XYtorial Point
st2's str = Tutorial Point

คำอธิบาย

  • st2 = st1 ทำให้ ทุก Byte ของ Array ถูก Copy ไปยัง st2.str
  • st1.str และ st2.str เป็น Array แยกกันสมบูรณ์ (Different Memory Locations)
  • การแก้ไขหนึ่งไม่ส่งผลต่ออีกตัว

เปรียบเทียบกับ Pointer Members

ข้อสังเกตสำคัญ

  1. Fixed-size Arrays ใน Struct/Class = Deep Copy อัตโนมัติ
  2. ไม่ต้องเขียน Copy Constructor / Assignment Operator สำหรับ Array Members
  3. แตกต่างจาก C-Style Arrays ที่ส่งผ่านฟังก์ชัน (Decay to Pointer)
  4. std::array<T, N> (C++11) ก็ทำ Deep Copy อัตโนมัติเหมือนกัน

ตัวอย่างเปรียบเทียบ Array vs Pointer

struct WithArray {
    int arr[5];  // Deep Copy อัตโนมัติ
};

struct WithPointer {
    int* ptr;    // Shallow Copy - ต้องเขียน Copy Constructor เอง
    WithPointer(int size) { ptr = new int[size]; }
    ~WithPointer() { delete[] ptr; }
    // ต้องมี Copy Constructor, Assignment Operator, Destructor (Rule of 3/5)
};

สรุป

ใน C++ Classes ไม่ต้องเขียน Copy Constructor/Assignment Operator สำหรับ Array Members เพราะ Default Behavior คือ Deep Copy แล้ว - นี่คือข้อดีของ Value Semantics ใน C++

Member TypeDefault Copy Behaviorต้องเขียน Copy Constructor?
Array (Fixed Size)Deep Copy ✓ไม่จำเป็น
PointerShallow Copy (Copy Address)จำเป็น (ถ้าต้องการ Deep Copy)
std::vector, std::stringDeep Copy (มี Copy Constructor ของตัวเอง)ไม่จำเป็น
Primitive Types (int, float, etc.)Value Copyไม่จำเป็น