Nesne tabanlı programlama nasıl çalışıyor?

Merhaba. Nesne tabanlı programlama ile ilgili merak ettiğim bir şey var. C++ derlenen bir dil ve nesne tabanlı programlama özelliği var. İşlemcimizin x86 Assembly kullandığını varsayalım. Bu durumda C++ x86 Assembly e derlenecek ancak x86 Assembly de sınıflar yok. Bu durumda nasıl derlenebiliyor? Birde Lua da class olmadığını öğrendim ama table lar ile nesne tabanlı programlama konseptini uygulayabiliyoruz. Ancak bu tıpatıp aynısı mı oluyor? Yoksa sadece class ların biraz benzeri mi? Yani Lua nın kullandığı table bir class ile aynı işlevi görüp dilin nesne tabanlı programlamayı desteklemesini sağlar mı? Nesne tabanlı programlama desteği olan diller (yorumlanan veya derlenen farketmez) bunu nasıl destekliyor? Mesela python da self.degiskenAdi = "yazbel" diyerek nesneye bir değişken ekleyebiliriz. Lua daki table ile bunu yapmak mümkün olur muydu? Mesela table ın içine tanımladığımız bir metod a bahsettiğim gibi bir kod yazabilir miydik ve self in tıpkı python daki gibi bir anlamı/işlevi olur muydu? Tabii illaki self olması gerekmiyor, C# aynı işlevi görmesi için this keyword unu tercih ediyor. Bilmiyorum diyebilecek kadar az Lua bilgim olduğundan böyle bir anahtar kelime var mı yok mu emin değilim.

Buradan lua proglamlama dilinde nasıl sınıf kullanacağınızı öğrenebilirsiniz:

Burası ise normal sınıf yapısı ve self kullanılarak yazılmış:

1 Beğeni

Complex sayilar, threading, dosyalar* da yok.

Derlemenin tanimi kodu assembly’e cevirmek. Assembly’de koddaki her ozellik olsaydi derlememize gerek kalmazdi, basit bir ceviri isimizi gorurdu.

C++'taki basit bir programi Python’a nasil ceviriyoruz?
Karmasik bir programi nasil ceviriyoruz?

Nesne tabanli programlamadan beklentin ne?

Hatta, butun sorulari goz onunde bulundurarak: Nesne tabanli programlamadan kasit ne? Fonksiyon kullanan programlamadan veya print kullanmayan programlamadan farki ne? Bir dilin destekleyip desteklememesini bu kadar onemli kilan ne? Ayni seyler OOP olmayan bir paradigmada yapilabilir mi?

self_degiskenAdi = "yazbel" diyerek de degisken yaratabiliyoruz. Noktali koddan farki ne?


*: Rastgele aklima gelen uc baska ozellik

2 Beğeni

Doğru, öyleyse tüm bu özellikler nasıl çalışabiliyor?

Yani yazdığımız kodu Assembly e uyarlıyoruz değil mi?

Programı Python da baştan yazarız. Python un desteklemediği yerleri ctypes ile ekleyebiliriz.

Bir dilin destekleyip desteklememesini önemli kılan şey sorunun kendisi. Nesne tabanlı programlama, bahsettiğiniz rastgele üç başka özellik Assembly de desteklenmiyorken tüm bu özelliklerin olduğu bir programı Assembly e derleyebiliyoruz. Bu nasıl mümkün olabiliyor? Sanırım Wormer_King in attığı linkler de sizin son sorunuzu cevaplıyor. OOP desteklemeyen Lua da aynı şeyleri yapabiliyoruz.

self_degiskenAdi ile global bir değişken oluştururken self.degiskenAdi ile oluşturduğumuz nesneye ait bir değişken tanımlayabiliyoruz.

Bildigimiz kadariyla hesaplanabilen butun fonksiyonlar Turing makinesine esdeger bir makine tarafindan hesaplanabiliyor. (bkz: Church–Turing Tezi (Thesis)) Turing makinasi o kadar basit bir makina ki, azicik karmasikliga sahip sistemler istem disi Turing-uyumlu (sonsuz hafizasi olsa Turing makinesine esdeger olacak) olabiliyor: Minecraft redstone devreleri, mayin tarlasi problemleri, x86 mimarisindeki mov instruction’i

Kisacasi bir programlama dilinde yapilan her sey baska bir programlama dilinde yapilabilir.

Yapilmak isteneni assembly’de yapiyoruz. Bastan yaziyoruz.

Python’un desteklemedigi yer yok.

    double complex z1 = 1.0 + 3.0 * I;
    double complex z2 = 1.0 - 4.0 * I;
    double complex sum = z1 + z2;

z1_r = 1.0
z1_i = 3.0
z2_r = 1.0
z2_i = -4.0
sum_r = z1_r + z2_r
sum_i = z1_i + z2_i

Cunku butun problemleri bitleri okuyup duruma gore bitleri yazan bir makineye indirgeyebiliyoruz. Uzerine cok bir sey koymaya gerek yok, bit gruplarina uint32, double gibi turler verip, temel islemler tanimlayip cagrisi mekanizmasi ekledigimizde cogu programlama dilinin temelini elde etmis oluyoruz zaten.

Uzerine 1 eklenen 32-bitlik degerin virtual base siniftan gelen DWORD turunde protected degisken olmasi islemciyi ilgilendiriyor mu sence?

Peki bu degiskenlerin farki ne?

3 Beğeni

Doğru. Bir oyundaki kırmızı kablolar ile turing makinesi yapılabiliyor :sweat_smile: sanırım gerçekten basit bir makina.

Hayır.

Sanırım şu şekilde açıklayabilirim:

class WebSite:
    def __init__(self, domain):
        self.domain = domain

yazbel = WebSite("forum.yazbel.com")
youtube = WebSite("youtube.com")

print(yazbel.domain)

yazbel.domain = "yazbel.com"

print(yazbel.domain)

domain isminde bir değişkeni hem yazbel nesnesi hem de youtube nesnesi için tanımlayabiliyoruz. Ancak sanırım bu da işlemci için bitlerden ibaret olduğu için bunun assembly de yapılmasını engelleyen hiç bir şey yok. Tabii class keyword unu kullanarak assembly de sınıf oluşturamıyoruz ama

Assembly de baştan farklı bir şekilde yazarak class ları kullanabiliriz (mesela Lua da table ları kullanmak gibi)
örnek olarak şu linki buldum c++ - How do objects work in x86 at the assembly level? - Stack Overflow
ve burada oluşturulan sınıf en son assembly de şu hali alıyor:

# The non-inline definition which actually returns a struct
addsub(int, int):
    lea     edx, [rdi+rsi]  # add result
    mov     eax, edi
    sub     eax, esi        # sub result
                            # then pack both struct members into a 64-bit register, as required by the x86-64 SysV ABI
    sal     rax, 32
    or      rax, rdx
    ret

# But when inlining, it optimizes away
foo(int, int):
    lea     eax, [rdi+rsi]    # a+b
    sub     edi, esi          # a-b
    imul    eax, edi          # (a+b) * (a-b)
    ret

:

yazbel_domain = "forum.yazbel.com"
youtube_domain = "youtube.com"

print(yazbel_domain)

yazbel_domain = "yazbel.com"

print(yazbel_domain)

Assembly’den once C’de, veya OO destegi olmayan baska bir daha-yuksek-seviyeli dilde nasil oldugunu dusunmek/arastirmak isteyebilirsin.

2006 tarihli bir ek$i sozluk entry’mden alinti yapayim:

#include <stdlib.h>
#include <stdio.h>

typedef struct class_araba {
	void (*constructor)(struct class_araba *self);
	void (*destructor)(struct class_araba *self);

	int tekerleksayisi;
	void (*git)(struct class_araba *self);
} Araba;

void git(Araba *self)
{
	printf("%i tekerlegimin uzerinde gidiyorum.\n", self->tekerleksayisi);
}

void constructor(Araba *self)
{
	self->tekerleksayisi = 0;
}

Araba *new_araba(void)
{
	Araba *ref;

	if ((ref = malloc(sizeof(Araba))) == NULL) {
		fputs("error creating new instance of Araba.", stderr);
		exit(EXIT_FAILURE);
	}

	ref->constructor = constructor;
	ref->destructor = NULL;
	ref->git = git;

	ref->constructor(ref);
	return ref;
}

void delete_araba(Araba *ref)
{
	if (ref->destructor) ref->destructor(ref);
	free(ref);
}

int main(void)
{
	Araba *a;

	a = new_araba();

	a->git(a);
	a->tekerleksayisi = 4;
	a->git(a);

	delete_araba(a);

	return EXIT_SUCCESS;
}

/*
> 0 tekerlegimin uzerinde gidiyorum.
> 4 tekerlegimin uzerinde gidiyorum.
*/

Dogru. Objeler sadece programcilara yardim eden kurgular. Hangi programlama dilinde ne yaparsan yap, assembly’de bir adet 8 veya 64 bitlik sayi uzerinde 7 temel isleme donusecek.

3 Beğeni

Doğru.

Sanırım kod ile daha da anlaşılır bir hale geldi. Söylediğiniz gibi nesne tabanlı programlama desteği olmayan yüksek seviyeli dilleri de inceleyeceğim. Soruda da olan Lua buna bir örnek sanırım.