EDA Playground'da Dene

Deep Copy vs Shallow Copy

Gün 2: Nesne Yönelimli Programlama (OOP) | Derin kopya ve sığ kopya arasındaki farklar

Kaynak Kod

// =============================================================================
// GUN 2 - Konu 7: Deep Copy vs Shallow Copy vs Handle Atamasi (Alias)
// =============================================================================

class Payload;
  int data[$];

  function new();
    data = {};
  endfunction

  function void add(int val);
    data.push_back(val);
  endfunction

  function void display(string prefix = "");
    $display("%sPayload@%p data=%p", prefix, this, data);
  endfunction
endclass

class Packet;
  int     id;
  string  name;
  Payload payload;  // baska bir nesneye referans (handle)

  // SADE: Her Packet kendi payload'ini varsayilan olarak yaratir
  function new(int id = 0, string name = "");
    this.id      = id;
    this.name    = name;
    this.payload = new();
  endfunction

  // Shallow Copy: Yeni Packet, ama payload handle'i paylasilir
  function Packet shallow_copy();
    Packet p = new(this.id, this.name);
    p.payload = this.payload;  // payload ortak (referans paylasimi)
    return p;
  endfunction

  // Deep Copy: Yeni Packet + Yeni Payload + icerik kopyasi
  function Packet deep_copy();
    Packet p = new(this.id, this.name); // yeni payload
    foreach (this.payload.data[i])
      p.payload.add(this.payload.data[i]);
    return p;
  endfunction

  function void display(string prefix = "");
    $display("%sPacket@%p: id=%0d, name=%s, payload@%p",
             prefix, this, id, name, payload);
    payload.display({prefix, "  "});
  endfunction
endclass

module deep_copy_vs_shallow_copy;
  function void build_original(output Packet p);
    p = new(1, "orijinal");
    p.payload.add(10);
    p.payload.add(20);
    p.payload.add(30);
  endfunction

  initial begin
    Packet original, alias_h, shallow, deep;

    $display("=== Deep Copy vs Shallow Copy vs Handle Atamasi ===\n");

    // -------------------------------------------------------------------------
    // 0) Orijinal nesne
    // -------------------------------------------------------------------------
    build_original(original);
    $display("--- Orijinal ---");
    original.display("  ");

    // -------------------------------------------------------------------------
    // 1) Handle atamasi (ALIAS) - kopya degil!
    // -------------------------------------------------------------------------
    $display("\n--- 1) Handle Atamasi (Alias) [KOPYA DEGIL!] ---");
    alias_h = original; // sadece handle kopyalanir, nesne DEGIL

    alias_h.id   = 2;
    alias_h.name = "alias";
    alias_h.payload.add(999);

    $display("  original == alias_h ? %s", (original == alias_h) ? "EVET (ayni nesne)" : "HAYIR");
    original.display("  Original: ");
    alias_h.display("  Alias:    ");
    $display("  ^^^ Tek nesne var; her sey ortak degisti");

    // -------------------------------------------------------------------------
    // 2) Shallow copy - yeni Packet, ama payload ortak
    // -------------------------------------------------------------------------
    $display("\n--- 2) Shallow Copy (Yeni Packet, Paylasilan Payload) ---");
    build_original(original);

    shallow = original.shallow_copy();
    shallow.id   = 3;
    shallow.name = "shallow";
    shallow.payload.add(777);

    $display("  original == shallow ? %s", (original == shallow) ? "EVET" : "HAYIR (farkli Packet)");
    $display("  original.payload == shallow.payload ? %s",
             (original.payload == shallow.payload) ? "EVET (payload ortak)" : "HAYIR");

    original.display("  Original: ");
    shallow.display("  Shallow:  ");
    $display("  ^^^ Packet ayri, ama payload ortak oldugu icin payload degisikligi orijinali etkiler");

    // -------------------------------------------------------------------------
    // 3) Deep copy - yeni Packet, yeni payload, icerik kopyalanir
    // -------------------------------------------------------------------------
    $display("\n--- 3) Deep Copy (Yeni Packet, Yeni Payload) ---");
    build_original(original);

    deep = original.deep_copy();
    deep.id   = 4;
    deep.name = "deep";
    deep.payload.add(888);

    $display("  original == deep ? %s", (original == deep) ? "EVET" : "HAYIR (farkli Packet)");
    $display("  original.payload == deep.payload ? %s",
             (original.payload == deep.payload) ? "EVET" : "HAYIR (payload ayri)");

    original.display("  Original: ");
    deep.display("  Deep:     ");
    $display("  ^^^ Payload ayri oldugu icin orijinal etkilenmez");

    $display("\n=== Demo Sonu ===");
    $finish;
  end
endmodule