Thread overview
Yapılar ve "Önceki Değerleri Kilitleyerek Aktarma"
Sep 27, 2012
Salih Dinçer
Oct 23, 2012
Salih Dinçer
Oct 23, 2012
Salih Dinçer
Oct 28, 2012
mert
September 27, 2012

Merhaba,

Ali hocam, D.ershane'de yapıları anlatırken çok basit ve de yerine göre çok çok önemli olabilecek bir sorun ile çözümüne değinmiş. Hem de çözümü aşağıda göreceğiniz üzere dahili halini de ilerleyen derslerde vermiş. Ancak bu çözüm sınıflarda çalışmadığını belirtmeliyim...

Örneği biraz zenginleştirdim, kısaca çalışan kod şöyle:

import std.conv, std.stdio;

struct Öğrenci {
 int numara;
 int[] notlar;

 this(this) { notlar = notlar.dup; }

 string toString() const {
     bool yazma;
     enum ders { Türkçe, Japonca, Matematik }
     string sonuç = to!string(numara) ~ " numaralı öğrencinin notları: (";
     foreach(adı, notu; notlar) {
         if(yazma) sonuç ~= ", ";
         sonuç ~= to!string(cast(ders)adı) ~ "=" ~ to!string(notu);
         yazma = true;
     }
     return sonuç ~ ")\n";
   }
}

void main() {
 auto Ali = Öğrenci(42, [70, 60, 90]);
      Ali.writeln("\tismi: Ali");
 auto Salih = Ali;
      Salih.numara = 41;
      Salih.writeln("\tismi: Salih");

 "Ali, Türkçe'den +1 not aldığında notu şu oldu: ".writeln(++Ali.notlar[0]);
 "Salih'e notlarına n'oldu?\n".writeln(Salih);
}

Çıktıyı vermiyorum çünkü denemeli (kurucu satırı aç/kapa yapmalı) ve farkı görmelisiniz. Ama tahmin edeceğiniz üzere, bahsedilen sorun referans üyeler içeren bir yapıyı başkasına kopyaladığınızda aslında her iki yapı tıpkı static olarak işaretlenmiş gibi tek bir değişkeni gösterecektir. O yüzden referans türler kullanırken dikkatli olmalı veya yukarıdaki gibi önlem almalısınız.

Ayrıca burada orijinal ismi "post blits" olan bir şey daha yapılıyor. Hiç bir parametre almayan kurucu işleve this ekleniyor: this(this) { ... } Böylece önceki yapının değerleri aynen aktarılırken ek olarak kurma işlevini genişletiyorsunuz.

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

September 27, 2012

Alıntı (Salih Dinçer):

>

bu çözüm sınıflarda çalışmadığını belirtmeliyim...

Öyle söyleyince bir sorun varmış gibi anlaşılabiliyor. Hayır, sınıflarda çalışmıyor çünkü sınıflarda böyle bir sorun yok. :)

Alıntı:

>

orijinal ismi "post blits"

Onun çoğul kullanımı olduğunu belirtmek gerek. Belgelerde "postblit" diye geçiyor:

http://dlang.org/struct.html#StructPostblit

Ali

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

October 23, 2012

Sanırım tatilde olduğum sırada es geçtiğim başlıklardan biriydi bu. Fazla irdelemediğimi ve unuttuğumu farkettim! Arzu ederseniz devam edelim...:)

Öncelikle bu örnek şurada geçmişti: http://ddili.org/ders/d/yapilar.html

Bunu sınıf ile yaptığımda (aşağıdaki) sorunun devam ettiğini görüyorum. Acaba opCall() gibi bir şey mi kullanmak lazım? Soruna ise kısaca kod içinde değindim...

import std.conv, std.stdio;

class Öğrenci {
 int numara;
 int[] notlar;

 //this(this) { notlar = notlar.dup; }/*
 this(int numara, int[] notlar){
   this.numara = numara;
   this.notlar = notlar;
 }//*/
 string toString() const {
     bool yazma;
     enum ders { Türkçe, Japonca, Matematik }
     string sonuç = to!string(numara) ~ " numaralı öğrencinin notları: (";
     foreach(adı, notu; notlar) {
         if(yazma) sonuç ~= ", ";
         sonuç ~= to!string(cast(ders)adı) ~ "=" ~ to!string(notu);
         yazma = true;
     }
     return sonuç ~ ")\n";
   }
}

void main() {
 auto Ali = new Öğrenci(42, [70, 60, 90]);
      Ali.writeln("\tismi: Ali");

 /* Yukarıda Ali nesnemiz Öğrenci olarak kuruluyor...
  * Buradaki ilk not Türkçe dersinden ve dikkat ilk notu 70
  * Aşağıda ise nesnenin bir kopyası çıkıyor ve farklılık
  * olsun diye numarası 41 yapılıyor...
  */

 auto Salih = Ali;
      Salih.numara = 41;
      Salih.writeln("\tismi: Salih");

 /* Kurulum işlemleri tamamlanınca Ali'nin notunu arttırıyoruz
  * Ama dikkat, Salih'in notu da değişiyor ve bu sorunu yapıda
  * this(this) { notlar = notlar.dup; } <-- satırı ile halletmiştik...
  */

 "Ali, Türkçe'den +1 not aldığında notu şu oldu: ".writeln(++Ali.notlar[0]);
 "Salih'e notlarına n'oldu?\n".writeln(Salih);
}

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

October 23, 2012

Anlıyorum hocam...

Aslında bu şekilde nesne kurulumunu genelde kullanmıyoruz ama bilmemizin çok önemli olduğunu düşünüyorum. Olur ya, benzer bir işlem yaparız ve kafa patlatırız neden hiç bir şey değişmiyor diye...:)

Teşekkürler...

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

October 23, 2012

Yapılar değer türü. Yani, nesneleri kopyalandıklarında veya atandıklarında soldaki nesne sağdakinden farklı bir nesne oluyor.

Ancak, senin de burada belirttiğin gibi, kendileri farklı nesne olsalar da üyelerini paylaşmaya devam edebiliyorlar.

Sınıflarda ise durum daha vahim: Kopyalama veya atama söz diziminde ikinci bir nesne yok. İki değişken aynı nesneye eriştirmey başlıyorlar. (Bu, Java (ve sanırım C#) türleri gibi.)

Sınıflarda çok önemli ve farklı iki kavram var:

  • Sınıf nesnesi: new ile oluşturulur ve hiçbir zaman kendi ismi yoktur.

  • Sınıf değişkeni: Sınıf nesnesine erişim sağlar. Kod içinde hep bunu kullanırız.

Şuradaki "Sınıf nesneleri ve değişkenleri", "Kopyalama", ve "Atama" başlıkları çok önemli:

http://ddili.org/ders/d/siniflar.html

(Aslında o bölümü biraz daha geliştirdim ve düzelttim ama daha siteye koymadım.)

Ali

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

October 23, 2012

Alıntı (acehreli):

>

Aslında o bölümü biraz daha geliştirdim ve düzelttim ama daha siteye koymadım.

Örneğin, oradaki kopyalama örneğini şöyle değiştirmişim:

class Sınıf
{
   Yapı   yapıNesnesi;
   char[] dizgi;
   int    tamsayı;

// ...

   this(Yapı yapıNesnesi, const char[] dizgi, int tamsayı)
   {
       this.yapıNesnesi = yapıNesnesi;
       this.dizgi       = dizgi.dup;
       this.tamsayı     = tamsayı;
   }

   Sınıf dup()
   {
       return new Sınıf(yapıNesnesi, dizgi, tamsayı);
   }
}

Ali

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

October 23, 2012

Alıntı (Salih Dinçer):

>

bilmemizin çok önemli olduğunu düşünüyorum.

Kesinlikle! :)

C++'tan gelenler her şeyi değer türü olarak görmeye alışmışlardır, Java gibi başka dillerden gelenler de herşeyi referans türü olarak görmeye alışmışlardır. D'de yapılar değer türü, sınıflar referans türü.

Baştan benim kafamı çok karıştırmıştı. :)

Ali

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

October 28, 2012

Salih merhaba,
Alıntı:

>
>
> ...//
>  string toString() const  // yerine
> //....
> ```

>
#3 numaralı mesajındaki örneğini denemek isteyen arkadaşlarımız için, haddim olmayarak minik bir hatırlatmada bulunmak isterim:
**string toString()** işlevi override olarak işaretlenmelidir.

..//
override string toString() const // olmalı. Çünkü bir önceki örneğimizde yapı içinde
// toString() işlevi kullanılıyor. Bu örnekte ise class
// kullanıyoruz. class toString() işlevini Object
// sınıfından otomatik olarak alıyor.
// O nedenle kendi türümüz için Object'ten gelen toString()
// işlevini baskılamamız gerekiyor.
//....



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