Jump to page: 1 2
Thread overview
March 07, 2013

Elimde bir class var ve ben bu classı kopyalamak istiyorum d de bunu nasıl yapabiliriz?

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 07, 2013
class Foo {
 int data;

 this(int data) {
   this.data = data;
 }
}

void main() {
 auto foo = new Foo(300);
 auto bar = foo;
 assert (bar.data == 300);
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 07, 2013

Bunu daha önce konuştuğumuzu hatırlıyorum ama gelişen durum gösteriyor ki unutmuşum...:rolleyes:

Belki Ali hocam derslerinde bile işlemiştir ama basit bir string'de bile .dup kullandığımıza göre sayılar dışında kalan tüm değişkenler/yapılara artık işaretçi gözüyle bakmalıyız. Yani işaretçi kopyalanıyormuş...:)

Peki hocam kopyalanan sınıfın, alt sınıfı olsaydı ama kurulurken alt sınıf boş olarak eşitlenmiş olsaydı n'apardık?

Hazırladığım şu örnekteki gibi:

class nar {
 int bilgi;
 kar sınıf;

 this(int veri) {
   this.bilgi = veri;
   sınıf = new kar();
 }

 nar kopyala() const @property {
   return new nar(bilgi);
 }

 override
 string toString() const @property {
   return sınıf.adı;
 }
}

class kar {
 string adı;

 this(string veri = "") {
   this.adı = veri;
 }
}

void main() {
 auto a = new nar(1000);
 auto b = a.kopyala();

 assert(a.bilgi == b.bilgi);
 // Yukarıda sorun yok her şey yolunda...

 a.bilgi = 999;
 assert(a.bilgi != b.bilgi);

 b.sınıf.adı = "b";
 assert(a.sınıf.adı != b.sınıf.adı);

 a = b.kopyala();
 assert(a.sınıf.adı != b.sınıf.adı);
 /* Ancak bu son satırda --------^
  * alt sınıfların üyeleri birbirine
  * eşitlenebilir mi?
  */
}

Dip Not: Alt sınıf benzetmesi yanlış oldu, "üyesi başka bir sınıf" demek daha doğru...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 07, 2013

Muhtemelen şu an cevap yazıyor olmalısın ama sanırım cevabın tek şıkkı bu olsa gerek:

 :  :  :

 this(int veri, string adı = "") {
   this.bilgi = veri;
   sınıf = new kar(adı);
 }

 nar kopyala() const @property {
   return new nar(bilgi, sınıf.adı);
 }

 :  :  :

Yani kopyala()'nın doğru çalışması için tüm üyelerine veri verebilmeli değil mi hocam?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 07, 2013

Kopyalama işlemini ben de bu şekilde yaptım. Ama yaptığım doğru gelmemişti. Salih hocamın dediği .dup gibi birşey vardır diye bekledim biraz araştırdım benim gibi böyle bir şey isteyenler varmış ama bu yöntemini kullanmaktan başka çare yok maalesef.

Teşekkürler

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 07, 2013

Alıntı (acehreli):

>

Ben bütün 'sınıf'ı göndermeyi düşünmüşüm, sen onun 'adı' üyesini. Duruma göre hangisi daha mantıklıysa... :)
Eğer dışarıda sınıfları birbirlerine eşitleyip kopyalayamıyorsak aynı şekilde sınıfı bütünüyle göndermek nasıl olabilir?

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 07, 2013

Anladım...

Şöyle kurucu yüklemesi aptım ama ya "access violation" hatası aldım ya da "assertion failure" uyumsuzluğu oldu:

class nar {
 int bilgi;
 kar sınıf;

 this(int veri) {
   this.bilgi = veri;
   sınıf = new kar();
 }

 this(int veri, kar ismi) {
   this.bilgi = veri;
   this.sınıf = ismi;
 }

 nar kopyala() @property {
   return new nar(bilgi, sınıf);
 }
}

Çünkü kopyalayı ilk kullandığımda başlangıçtaki aynı üyeyi (kar sınıf) paylaşmasına neden oluyor. Bende ilk aklıma gelen çözüm ile ikincisinin karışımını denediğimde "access violation" hatası alıyorum...

 this(int veri, kar ismi) {
   this.bilgi = veri;
   this.sınıf.adı = ismi.adı;
 }

Dikkat ederseniz kopyala() işlevinin yanındaki const takısını iptal ettim çünkü bu sefer de başka hata veriyordu. Herhalde sınıf bir immutable yapı olmadığı için. Çünkü string verirken sıkıntı yaşatmamıştı.

Off....:(

Kafam karıştı, ilk çözüm içime sindi aslında. Bir tek üye olarak kullandığınız sınıfın içeriğini bilmeniz gerekiyor. Düşünsenize bu harici bir sınıf olsaydı ve sadece bize bildirilen üyeleri bilseydik gerçek manada kopyalayamazdık. Yine bir of, çok kafa karışıtırıcı!

Sevmedim bu işi...:D

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 07, 2013

Yanıltıcı. :) Sınıflar referans türü olduğu için yine de tek nesne var. foo ve bar değişkenleri aynı nesneyi gösteriyorlar.

Sınıflarda bir üye işlev yazmak şart: dup(), clone(), kopyası(), vs. gibi bir isim uygundur:

   Foo kopyası() const {
       return new Foo(/* ... */);
   }

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 07, 2013

Alıntı (Salih Dinçer):

>

sayılar dışında kalan tüm değişkenler/yapılara artık işaretçi gözüyle bakmalıyız. Yani işaretçi kopyalanıyormuş...:)

Biraz karışık söyledin çünkü buradaki ayrımın değer türü ile referans türü arasında yapılması gerekiyor. O yüzden yapılarda böyle bir sorun yok. Onlarda da nesne kopyalanır.

Kısa hatırlatma: Atama işlemi sonucunda soldaki değişkenin değeri değişiyorsa değer türüdür. Eğer soldaki de sağdakinin eriştirdiği nesneye erişim sağlamaya başlıyorsa referans türüdür.

Alıntı:

>

Peki hocam kopyalanan sınıfın, alt sınıfı olsaydı ama kurulurken alt sınıf boş olarak eşitlenmiş olsaydı n'apardık?

Örneğine bakılırsa alt sınıf değil de üye değişken kastediyorsun.

Ancak, bunu cevaplamaya geçmeden önce sınıf nesnesi kopyalamanın aslında sanıldığı kadar yaygın bir ihtiyaç olmadığını belirtelim. Zaten bu yüzden bu kavram kitapta ve D projelerinde sık görülmüyor.

C++'ta yapılar ve sınıflar değer türüdür. Java'yı tasarlayanlar bunun yanlış olduğunu düşündükleri için Java'nın sınıflarının referans türü olarak tasarlamışlardır. (Başka çok dilde de öyle.) D ise yapıları C++'taki gibi değer türü, sınıfları da Java'daki gibi referans türü yapmıştır.

Kendi deneyimlerime bakarsam bunun doğru olduğunu görüyorum. Kendi C++ projelerimizde sınıf nesneleri hemen hemen her zaman tek oluyorlar. Nesne kopyalama yaygın bir kavram değil. Üstelik, programın hata atıldığında da doğru işleyebilmesi (exception safety) için nesnelere shared_ptr ile erişilmesi gerekiyor. Öyle olunca da C++'ta referans türü kavramını gerçekleştirmiş oluyoruz.

Sonuçta, tasarımlarda hangi türün değer türü hangisinin referans türü olacağı genellikle baştan biliniyor. Referans türüyse de kopyalamak pek gerekmiyor.

Notlarımı kodun içine yazayım:

class nar {
 int bilgi;
 kar sınıf;

 this(int veri) {
   this.bilgi = veri;
   sınıf = new kar();
   /* [Ali] O koddan anlaşıldığına göre 'sınıf' üyesi bütünüyle bu sınıfın
    * özel bir üyesi kabul ediliyor. Dışarıdan verilen bir bilgi değil.
    */
 }

 nar kopyala() const @property {
   return new nar(bilgi);
   /* [Ali] Yukarıdaki açıklamaya uygun olarak bu nesnenin kopyalanması için
    * 'bilgi'nin aktarılması yeterli çünkü yeni nesne de kendi 'sınıf'ını
    * oluşturacak.
    *
    * Eğer 'sınıf'ın da kopyalanması istenseydi belki de özel bir kurucu
    * işlev kullanılabilir ve 'sınıf'ın bir kopası da gönderilebilirdi:
    *
    *     return new nar(bilgi, sınıf);
    */
 }

 override
 string toString() const @property {
   return sınıf.adı;
 }
}

class kar {
 string adı;

 this(string veri = "") {
   this.adı = veri;
 }
}

void main() {
 auto a = new nar(1000);
 auto b = a.kopyala();

 assert(a.bilgi == b.bilgi);
 // Yukarıda sorun yok her şey yolunda...

 a.bilgi = 999;
 assert(a.bilgi != b.bilgi);
 /* [Ali] Mantıklı çünkü 'bilgi' üyeleri farklı.
  */

 b.sınıf.adı = "b";
 assert(a.sınıf.adı != b.sınıf.adı);
 /* [Ali] O da mantıklı çünkü her nesnenin kendi 'sınıf' üyesi de farklı.
  */

 a = b.kopyala();
 assert(a.sınıf.adı != b.sınıf.adı);
 /* Ancak bu son satırda alt ---^
  * sınıfların üyeleri birbirine eşitlenebilir mi?
  */
 /* [Ali] Evet, eşitlenebilir. Eğer 'sınıf'larının aynı nesneyi
  * paylaşmalarını istersek 'sınıf'larını eşitleriz. Eğer onların farklı
  * olmalarını ama 'adı' üyelerinin eşit olmalarını istersek de onları
  * eşitleriz.
  *
  * Bunun nasıl yapılacağı tasarıma göre değişir ama dışarıdan yapmak yerine
  * üye işlevler kullanmak çok daha iyi olur.
  */
}

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

March 07, 2013

Alıntı (Salih Dinçer):

>

cevabın tek şıkkı bu olsa gerek:

Ben bütün 'sınıf'ı göndermeyi düşünmüşüm, sen onun 'adı' üyesini. Duruma göre hangisi daha mantıklıysa... :)

Eğer bu kurucu yalnızca bu sınıfın kendi işi için yararlıysa 'private' olarak işaretlenmesinde de yarar var.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

« First   ‹ Prev
1 2