| |
| Posted by Ali Çehreli in reply to Salih Dincer | PermalinkReply |
|
Ali Çehreli
Posted in reply to Salih Dincer
| On 4/16/22 02:53, Salih Dincer wrote:
> Konu modern C++ ile ilgili ama doğrudan D ve birçok derlenebilir dili de
> ilgilendiriyor.
Evet, üye işlevlerin nasıl gerçeklendiklerini anlatmış. (Sanal işlevlere daha sonra geçeceğini söylemiş.)
> Bazen derleyicinin bize verdiği ```__FUNCTION__``` gibi özel dinamik
> değerler var ve sanırım bunların birçoğu şablon programlama ile
> kullanılıyor;
__FILE__, __FUNCTION__, ve __LINE__ C'den gelir ve örneğin hata mesajlarında yararlıdır. D bunlara bir kaç tane daha ekler:
https://dlang.org/spec/expression.html#specialkeywords
D, bu özel değişkenler varsayılan parametre değeri olarak kullanıldıklarında işlevin çağrıldığı yerin belirlenmesini sağlarlar.
Ben, kütüphanemin C arayüzünden hata atılmasını engellediğim yerde yararlanmıştım:
import std.exception;
import std.format;
import std.string;
// Kütüphanemin işlevlerinin döndürdüğü hata nesnesi
extern (C)
struct Sonuc {
int hata; // Hata kodu
const(char) * hata_mesaji;
}
// Bu, kütüphanemin C arayüzünün bir işlevi olsun.
// (İsminde o yüzden Unicode kullanmıyorum.)
extern (C)
Sonuc yararli_bir_sey_yap(int i) {
return tried!({
// İşlevimin bütün işlemleri bu delegate içinde hallediliyor.
// İstediğim D olanağını kullanabiliyorum.
// Bu olanaklar hata atabiliyorlar. tried, atılan hatayı
// yakalayıp C'ye anlamlı bir hata mesajı döndürüyor.
// (tried'ı biraz aşağıda gösteriyorum.)
//
// Örneğin, enforce() hata atar:
enforce(i > 0, format!"Sıfırdan büyük olmalıydı. (%s)"(i));
});
}
Sonuc tried(alias dg, // <-- İşletilen işlemler
string dosya = __FILE__, // Yararlı bilgiler
string işlev = __FUNCTION__,
size_t satır = __LINE__)() {
try {
dg();
} catch (Exception hata) {
return Sonuc(1, format!"%s:%s:%s: %s"(dosya, işlev, satır, hata.msg).toStringz);
}
// Burada Error da yakalanabilir ve çabucak exit(1) yapılmalıdır;
// gözardı ediyorum.
// Hata yok
return Sonuc(0, null);
}
// Bu, kütüphanemizi kullanan bir C kodu örneği olsun:
void kullanici_ornegi() {
Sonuc sonuc = yararli_bir_sey_yap(-42);
if (sonuc.hata) {
import core.stdc.stdio;
printf("HATA: %s.\n", sonuc.hata_mesaji);
}
}
void main() {
kullanici_ornegi();
}
> acaba sınıflar ile ilgili bilmemizin iyi olabileceği özel
> şeyler var mı?
İşlevlere gönderilen 'this'ten başka, sanal işlevi olan sınıflarda vtbl pointer diye 'void*' türünden bir gösterge de olur. D'de ek bir maslaf, Java'dan gelmiş olan 'monitor' kavramıdır. O bir 'void*' daha ekler. (Ama sınıf extern(C++) ise 'monitor' bulunmaz.)
> Çünkü bazen typeid, typeof gibi şeyler yetersiz
> kalabililiyor.
Ben onları çok nadiren kullanıyorum çünkü pek gerekmiyorlar. Sen nasıl yetersiz buluyorsun?
Ali
|