Yazan : Şadi Evren ŞEKER

Bu yazının amacı, nesne yönelimli programlama ortamlarında (object oriented programming) kullanılan iki temel kopyalama işlemini anlatmaktır.

Literatürde bir nesnenin kopyalanması için geçen iki terim bulunur:

  • Sığ kopyalama (shallow copying)
  • Derin kopyalama (deep copying)

Sığ kopyalama basitçe bir nesnenin referansını gösteren nesne atfının, farklı bir nesne atfına atanmasıdır. Örneğin aşağıdaki kodu inceleyelim :

public class kedi{

   int boy;

   int kilo;

}

public class test{

   public static void main(String args[]){

      kedi tekir = new kedi();

      tekir.boy = 40;

      tekir.kilo=6;

      kedi mırnav = new kedi();

      mırnav = tekir;

}

Yukarıdaki kodun son satırında bulunan mırnav = tekir; ataması (Assignment) yapılmadan önce hafızdaki (RAM) durum aşağıdaki şekildedir:

İlgili atama satırı çalıştıktan sonra mırnav ile tekir aynı adresi göstermeye başlar:

Yukarıdaki bu atamaya sığ atama (shallow copying) ismi verilir çünkü hafızada iki nesne atıfı tarafından da aynı nesne gösterilmektedir ve birisinde yapılan değişiklik diğerini etkiler. Örneğin aşağıdaki satırı ele alalım:

mırnav.boy = 35

Bu satırdan sonra tekir isimli nesne atfının da boy üyesi 35 değerine sahip olmaktadır.

Peki, atamadan önceki mirnav tarafından gösterilen ve henüz değerleri bulunmayan nesne ne olur? Sonuçta bu nesnenin içerisindeki üyelere (members) değer konulmamış olsa da (boy ve kilo değeri verilmemiştir), new operatörü ile tanımlanmış bir hafız alanı söz konusudur ve bu alan hafızada yer kaplar. Sorunun cevabı programlama diline göre değişir. Örneğin java için garbage collector isimli bir işlem devreye girerek bu alanı temizler. C++ dilinde ise bu alan uzayda kaybolur (lost in space) ve C++ programcılarının bu tip hatalara karşı dikkatli olması ve free() fonksiyonunu kullanarak hafızadan kaldırması gerekir.

Gelelim derin kopyalamaya (deep copying)

Bu durumu da aynı sınıf tanımı üzerinden (kedi sınıfı) aşağıdaki kod ile anlamaya çalışalım:

public class kedi{

int boy;

int kilo;

public void kopyala(kedi x){

this.boy = x.boy;

this.kilo= x.kilo;

}

}

public class test{

public static void main(String args[]){

kedi tekir = new kedi();

tekir.boy = 40;

tekir.kilo=6;

kedi mırnav = new kedi();

mirnav.kopyala(tekir);

}
}


Yukarıdaki kopyala satırı, parametre olarak aldığı, kedi sınıfından bir nesnenin içeriğini kendisine kopyalar. Örneğimizdeki mirnav nesnesi, tekir nesnesinin içeriğini kendisine kopyalamıştır.

Yukarıdaki bu işlemin hafızdaki (RAM) görüntüsü ise aşağıdaki temsili resimde verilmiştir:

Yukarıda gösterilen derin kopyalama işleminin bir benzerini yapmak için yapıcı fonksiyonlardan (constructor function, inşa fonksiyonu) faydalanılabilir. Bunun için aşağıdaki kodda olduğu gibi bir yapıcı fonksiyon tanımlamak yeterlidir.


public class kedi{

int boy;

int kilo;

public kedi(kedi x){

this.boy =x. boy;

this.kilo= x.kilo;

}

}

public class test{

public static void main(String args[]){

kedi tekir = new kedi();

tekir.boy = 40;

tekir.kilo=6;

kedi mırnav = new kedi(tekir);
}
}


Yukarıdaki kodda bulunan bu yapıcı fonksiyona ayrıca özel olarak kopyalama yapıcısı (copy constructor) ismi de verilmektedir.

Yorumlar

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir