August 29, 2012

Alıntı (Salih Dinçer):

>

(Dici...:))

İyiymiş :)

Alıntı (Salih Dinçer):

>

Örneğin şu an elimde bir CPP project var ve ben o gelenekten yetişmediğim için bazı yapıları anlayamıyorum! Özellikle aşağıdaki kod; yıldız yerinez adres işaretinin sola bitişik yazılmış. Ayrıca dönüş değeri belli olmayan (zannedersem void?) işlevler görüyorum. Bu aşağıdaki sadece biri...:(

> 	Settings& operator=(const MethodConfig& method_config)
> 	{
> 		reinterpret_cast<MethodConfig&>(*this) = method_config;
> 		return *this;
> 	}
> };
> ```

>

Burada bir olay yok. Burada 'Settings & operator=(const MethodConfig &)' kısmı kopyalayarak atama işlecinin farklı görev yüklenmiş hali.

Bunun D karşılığını yazmaya gerek yok diye düşünüyorum ama emin değilim.

'*this' demek nesnenin kendisi demek. İki tane nesneyi birbirine atamış. Sonra 'reinterpret_cast' ile taban sınıfa bir referansa çevirmiş.

C++ kodu olarak düşününce bunlar çerez sayılır  ;-)

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

C'de dizi diye ayrıca bir tür olmadığı için öyle oluyor. D'de C dizilerine en yakın olan şey statik dizilerdir (uzunluğu derleme zamanında bilinen).

Burada bir şey daha anlıyoruz: D'de dizi içine dizi yerleştirdiğimizi sanıyoruz ama aslında içtekiler dilim. Dilimlerin de dizi kavramıyla tek yakınlıkları, D çalışma ortamının (D runtime) bizim için yönettiği elemanlara erişim sağlamak.

Salih, gördüğün 16 bayt herhalde hizalama (alignment) ile ilgilidir. Şurada "Türlerin .alignof niteliği" başlığında var:

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

Belki 64 veya 32 bit derleme arasında fark görebilirsin.

Ali

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

August 29, 2012

Şimdi biraz daha düşündüm: Benim sistemimde 16 bayt tutmasının nedeni, dilimlerin iki üyesinin de 8 bayt olmasından geliyor: size_t türünde uzunluk ve eleman göstergesi.

Ali

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

August 29, 2012

Alıntı (Salih Dinçer):

>

yıldız yerinez adres işaretinin sola bitişik yazılmış.

Öyle kullanıldığında adres işareti değil, "referanstır". D'deki 'ref'in eşdeğeri.

Alıntı:

>

Ayrıca dönüş değeri belli olmayan (zannedersem void?) işlevler görüyorum.

D ile aynı: Dönüş değeri belli olmayan değil, dönüş değeri olmayan demek.

Alıntı:

>

Bu CPP kodunun D karşılığı olabilir mi?

Tesadüf, daha geçen hafta "Kurucu ve Diğer Özel İşlevler" bölümüne eklemeler yaptım ama henüz siteye koymadım. Yapıların opAssign() işleci tanımlanırken dönüş türü konusunda üç seçenek var.

Özel bir nedeni yoksa dönüş türü yapının türü olabilir:

struct Süre
{
   int dakika;

   Süre opAssign(Süre sağdaki)
   {
       writefln(
           "dakika, %s değerinden %s değerine değişiyor",
           this.dakika, sağdaki.dakika);

       this.dakika = sağdaki.dakika;

       return this;
   }
}
// ...
   auto süre = Süre(100);
   süre = Süre(200);          // atama

Ondan sonra şöyle bir bölüm ekliyorum:

Alıntı:

>

Eniyileştirmeler

Dönüş türünün Süre olarak seçilmesinin nedeni, birden fazla nesnenin aynı satırda atandığı söz diziminin desteklenmesidir:

>     auto a = Süre(1);
>     auto b = Süre(2);
>     auto c = Süre(3);
>
>     a = b = c;
> ```

>
> Önce c nesnesi b'ye, sonra da o atama işleminin döndürdüğü Süre nesnesi a'ya atanır:
>
> 'dakika, 2 değerinden 3 değerine değişiyor
> dakika, 1 değerinden 3 değerine değişiyor'
>
> Yukarıdaki gibi zincirleme atama işleminin kullanılmasının önemli olmadığı durumlarda opAssign'ın dönüş türü void olarak seçilebilir ve dolayısıyla return this satırı da yazılmaz:
>
>
>
void opAssign(Süre sağdaki)
{
    // ... 'return this;' yoktur
}
>

Yapının kopyalanmasının fazla zaman aldığı durumlarda hem parametre hem de dönüş türü ref const olarak işaretlenebilir:

>     ref const(BüyükBirTür) opAssign(ref const(BüyükBirTür) sağdaki)
>     {
>         // ...
>     }
> ```

>

Salih, O C++ kodu 'a = b = c' gibi bir yazımı desteklemek için *this ile "bu nesnenin kendisine referans" döndürüyor. Yukarıda dönüş türü 'ref' olan son D işlevinin eşdeğeri.

Ali

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

Ancak şimdi deneme fırsatı bulabiliyorum...

Aslında C++'da std::pair<int, int> diye bir dönüş türü sorunuyla da ilgilenmek zorundaydım. Neyse ki onu iki elemanlı bir dilim şeklinde döndürerek kolaylıkla hallettim. Fakat şu son konuştuğumuz mevzu denediğimde şu hatayı aldım:

Alıntı:

>

'pt.d(100): Error: function pt.Settings.opAssign has no return statement, but is expected to return a value of type const(MethodConfig)
make: *** [p] Hata 1'

Böyle bir hata verince bir şey döndürmek gerektiğini anlıyorum ve şu şekilde kodluyorum:

 ref const(MethodConfig) opAssign(ref const(MethodConfig) sağdaki)
 {
       this = sağdaki;
       return this;
 }

O zaman da 'Error: cast(const(MethodConfig))this.method_config is not an lvalue' hatası alıyorum. Çünkü bir şeyleri ters yapıyor olmalıyım. Peki başa saralım; nereden gelmişim...

'(Korkmayın, çocukluğuma inmeyeceğim...:))'

Aslında temelde iki yapımız (tabi onların da üye yaptığı başka yapılar da) var. Bunu yukarıda paylaşmıştım ama yapılarda miras alma D'de olmasa gerek? Ben de opAssign'lı yapıyı ('''struct' Settings : 'public' MethodConfig { ... }'') şu şekilde yaptım:

struct Settings {
 MethodConfig method_config;
 alias method_config this;
 // ...
}

Peki sizce nerede hata yaptım?

Teşekkürler...

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

August 30, 2012

Hocam, büyük zahmet verdim kusura bakma ama bu özelliğe sanırım D'de ihtiyacımız yokmuş! Çünkü...

Öncelikle bu özelliği en son tarif ettiğin şekilde uygulayınca derleme sorunu kalktı. Ben Settings yapısı içinde kullanmıştım ki herhalde hatalı olduğum kısım burasıydı. Ama bu sefer de matematiksel hesaplar karıştı, çarman çurman oldu...:)

Dedim, şunu kaldırayım bakalım ne olacak? Çalıştı! Yani anlamıyorum ama CPP'de gereken D'de olayları karıştırıyor. Yakında kodu yayınladığımda tekrar birlikte bakarız...

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

August 30, 2012

İşte ihtiyaç duymadığının kanıtı:
Alıntı:

>
> 	// Set the calculation method
> 	void set_calc_method(CalculationMethod new_calc_method)
> 	{
> 		calc_method = new_calc_method;
> 		settings = method_params[calc_method]; // opAssign olmazsa bu satır CPP'de patlıyor!
> 	}
> ```

>
Belki fotoğrafın tamamını görmediğiniz için pek bir şey anlaşılmıyordur. Ama kısaca anlatırsam, bu işlev kurucu işlev içinde çağrılıyor ve D'de opAssign işlevine ihtiyaç duymuyor...

Bu arada, "geri dönüş değeri belli olmayan işlevler (solu boş olan) CPP'de nedir?" gibi bir sorum olmuştu. Meğer o kurucu işlevmiş. Merak ediyorum da D'deki this() işlevi CPP'deki sınıflarda yok mudur?

Teşekkürler...

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

Son sorumu geri alıyorum; meğer sınıf ile aynı ismi taşıyan işlev kurucu imiş...:)
Alıntı:

>

Kurucu Fonksiyonlar (Constructors)
Kurucu fonksiyonlar üyesi oldukları sınıftan bir nesne yaratılırken kendiliğinden canlanırlar. Bu tür fonksiyonlar bir nesnenin kurulması aşamasında yapılması gereken işleri, örneğin verilere uygun başlangıç değerleri atamak için kullanılırlar. Kurucu fonksiyonlar üyesi oldukları sınıf ile aynı ismi taşırlar. Kurucular parametre alırlar, ancak geri dönüş değerleri yoktur. Geri dönüş tipi olarak herhangi bir tip (void bile) yazılmaz.

Kurucu fonksiyonlar nesne yaratılırken sınıfın dışından sınıfın açık (public) üyeleri arasında yer almalıdırlar. Kurucu fonksiyonlar işlevlerine ve yapılarına göre bazı alt gruplara ayrılırlar. İlk grupta parametre verilmeden çağrılabilen parametresiz kurucu
fonksiyonlar yer alır.
©1999-2002 Dr. Feza BUZLUCA

Son günlerde şuradaki (http://ninova.itu.edu.tr/tr/dersler/elektrik-elektronik-fakultesi/21/blg-252e/ekkaynaklar?g397) dersleri takip etmeye başladım. CPP'yi tamamen öğrenemesem de şu basit soruları aşmalıyım... :nuts:

Ayrıca hocanın sitesinde Türkçe belgeler de var: http://web.itu.edu.tr/~buzluca/cpp/

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

August 30, 2012

Alıntı (Salih Dinçer):

>

Alıntı:

>

'pt.d(100): Error: function pt.Settings.opAssign has no return statement, but is expected to return a value of type const(MethodConfig)
make: *** [p] Hata 1'

Tahmin: Dönüş türünü void yapmak yerine const(MethodConfig) olarak bıraktın ve return deyimi yazmadın.

Alıntı:

>

Böyle bir hata verince bir şey döndürmek gerektiğini anlıyorum ve şu şekilde kodluyorum:

>   ref const(MethodConfig) opAssign(ref const(MethodConfig) sağdaki)
>   {
>         this = sağdaki;
>         return this;
>   }
> ```

> O zaman da 'Error: cast(const(MethodConfig))this.method_config is not an lvalue' hatası alıyorum. Çünkü bir şeyleri ters yapıyor olmalıyım.

Olaylar karışmaya başlayınca o kodu bir kenara bırak ve basitten başla. Şunlar bende derleniyor:


struct S
{
void opAssign(S sağdaki) const
{}
}

struct MethodConfig
{
ref const(MethodConfig) opAssign(ref const(MethodConfig) sağdaki)
{
// Bunu yapmayın; yine bu işlevi çağıracağı için takılır.
// this = sağdaki;
return this;
}
}

void main()
{
S s0, s1;
s0 = s1;

MethodConfig m0, m1;
m0 = m1;
}



Alıntı:
> yapılarda miras alma D'de olmasa gerek?

Doğru.

Alıntı:
> Ben de opAssign'lı yapıyı ('''struct' Settings : 'public' MethodConfig { ... }'')  şu şekilde yaptım:
>
>

struct Settings {
MethodConfig method_config;
alias method_config this;
// ...
}

>

Peki sizce nerede hata yaptım?

Teşekkürler...

Aşağıdakinden farklı herhalde çünkü bu da derleniyor:

struct MethodConfig
{
   ref const(MethodConfig) opAssign(ref const(MethodConfig) sağdaki)
   {
       // Bunu yapmayın; yine bu işlevi çağıracağı için takılır.
       // this = sağdaki;
       return this;
   }
}

struct Settings {
 MethodConfig method_config;
 alias method_config this;
 // ...
}

void main()
{
   Settings s0, s1;
   s0 = s1;
}

Ali

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

August 31, 2012

Alıntı (Salih Dinçer):

>

Son günlerde şuradaki (http://ninova.itu.edu.tr/tr/dersler/elektrik-elektronik-fakultesi/21/blg-252e/ekkaynaklar?g397) dersleri takip etmeye başladım.

Oradaki notları inceledim ancak pek beğenmediğimi söylemeliyim :-(

ComplexT ComplexT::operator+(const ComplexT& z) const
{
   double re_new, im_new;
   im_new = re + z.re;
   im_new = im + z.im;
   return ComplexT(re_new, im_new);
}

Örneğin 'operator+=' işlecine de ihtiyacımız olacak.

Karmasik & operator+= (Karmasik const & diger)
{
   reel_ += diger.reel_;
   sanal_ += diger.sanal_;
   return *this;
}

O zaman 'operator+''yı şu şekilde yazabiliriz:

Karmasik operator+ (Karmasik birinci, Karmasik const & ikinci)
{
   return birinci += ikinci;
}

Referanslarla ilgili kısımda referans olarak 'int' döndürmüş. Ancak temel türlerde referans olarak belirlemek bir hız farkına neden olmaz.

Nesne yönelimli programlama bölümünde dinamik olarak oluşturduğu Nokta nesnelerini silmeyi anlatmış. Ama dinamik olarak bellek ayrıldığında programda bir hata oluşursa bellek sızıntısı oluşacaktır.

Ben olsam illa nokta kullanmak gerekiyorsa Stroustroup'un kitabındaki şu örneği kullanırdım.

#include <iostream>
#include <memory>
using std::cout;
using std::auto_ptr;

struct Nokta
{
   double x, y;
};

struct Dikdortgen
{
   double x, y, w, h;
};

// Hayali bir sınıf :o

class Arac
{

public:

   virtual ~Arac ()
   {}

   virtual void fareTiklandiginda (const Nokta & nokta) = 0;
   virtual Nokta noktaOgren () const = 0;
};

class Kalem : public Arac
{
   Nokta nokta_;
   bool fareBasiliMi_;

public:

   Kalem ()
       : fareBasiliMi_ (false)
   {}

   virtual void fareTiklandiginda (const Nokta & nokta)
   {
       nokta_ = nokta;
       cout << "Bitis noktası (" << nokta_.x << ","<< nokta_.y << ") "
            << "olan bir cizgi ciziyorum!" << '\n';
       fareBasiliMi_ = true;
   }

   Nokta noktaOgren () const { return nokta_; }

};

class Secim : public Arac
{
   Nokta nokta_;
   bool fareBasiliMi_;
   Dikdortgen secim_;

public:

   Secim ()
       : fareBasiliMi_ (false)
   {}

   Secim (const Nokta & nokta)
       : nokta_ (nokta)
   {}

   virtual void fareTiklandiginda (const Nokta & nokta)
   {
       secim_.x = nokta_.x;
       secim_.y = nokta_.y;
       secim_.w = nokta.x;
       secim_.h = nokta.y;

       cout << "Baslangic noktasi ("
            << secim_.x << "," << secim_.y << ") "
            << "bitis noktasi ("
            << secim_.w << "," << secim_.h << ") "
            << "olan bir dikdörtgen ciziyorum" << '\n';
       nokta_ = nokta;
   }

   Nokta noktaOgren () const
   {
       return nokta_;
   }

};

class Cizici
{
   auto_ptr<Arac> arac_;
   Nokta nokta_;


   Cizici (Cizici const &);
   Cizici & operator= (Cizici const &);

public:

   Cizici ()
       : arac_ (new Kalem)
   {}

   void fareTiklandiginda (const Nokta & nokta)
   {
       arac_->fareTiklandiginda (nokta);
   }

   void secimAraciniSec ()
   {
       nokta_ = arac_->noktaOgren ();
       arac_.reset (new Secim (nokta_));
   }
};


int main ()
{
   Cizici cizici;
   Nokta nokta = {3, 5};

   cizici.fareTiklandiginda (nokta);
   cizici.secimAraciniSec ();

   nokta.x = 7;
   nokta.y = 10;

   cizici.fareTiklandiginda (nokta);

}

Kısacası C++ öğrenmen gerekiyorsa güzel bir C++ kitabı almanı tavsiye ederim.

http://amzn.com/020170353X

Eğer Amazon'dan almak istemiyorsan pandora gibi kitapevleri bu kitapları yurtdışından getirebiliyorlar.

Ben bile asıl amacım C öğrenmek olmamasına rağmen Ali beyin tavsiyesiyle ilk C kitabımı aldım.

http://amzn.com/0672326973

Çünkü bir noktada örneğin bir C kodunun D sürümünü yazmak gerekiyor. O zaman anlamadığım bir nokta olduğunda açıp bakabilirim.

Ayrıca ilk izlenimlerim gayet güzel. Hatta sadece bir başlangıç kitabı olmaktan çok, şimdiye kadar bilmediğim C'nin ileri düzey ayrıntılarını da anlattığını söyleyebilirim.

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