Thread overview
C++, D, C# ve Object Pascal Sınıf ve Yapı Farkları
Aug 20, 2018
İbrahim
Aug 20, 2018
kerdemdemir
Aug 23, 2018
İbrahim
Aug 24, 2018
İbrahim
August 20, 2018

Selamün Aleyküm;

C++'da sınıflar da yapılar da değer türlüdürler:

// C++ - Varsayılan üye erişim yöntemleri dışında aslında ikisi de aynı.
class Example
{
};

struct Example
{
}

Lakin D, C#, Object Pascal dillerinde sınıflar referans türlü, yapılar ise değer türlü oluyor:

// D
class Example // Referans türlü
{
}

struct Example // Değer türlü
{
}

// C#'da da aynı:
..

// Object Pascal'da da aynı:
type
 Example = class // Referans türlü
 end;

type
 Example = record // Değer türlü
 end;

Bu dillerde sınıflar ve yapılar varsayılan olarak bu şekildeler ama C++ neden bu dillerden farklı bir şekilde davranarak sınıfları değer türlü oluşturuyor? Sizce hangisi daha mantıklı? Varsayılan olarak sınıfları değer türlü mü tanıtmalı yoksa referans türlü mü?

Teşekkürler.

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

August 20, 2018

Bu tam Ali Abinin yorumlaması gereken bir soru sanki.

Bence dilin için çöp toplayıcı olduğu için sınıfları referans türü yapma olasılığı oluyor. Eğer C++ çöp toplayıcısı olmayan bir dil ise bunu kullanıcıya bırakmak en mantıklısı sonuçta objenin sorumluluğu kullanıcının üstünde. Bu sorumluluğu kullanıcıdan almayan C++ gibi dillerin bu tür konularda C harici bir davranış göstermesi yanlış olur bence.

Eğer referans türünün geri verilmesi destekleyen bir dil ise sınıfların referans türü yapılmasının avantajları obje yönelimli programlamayı kulllanmaları gibi görüyorum. Bu dillerin bazılarının yapıları değer olarak belirlemesinin sebebinide her nesne süper polimorfik yeteneklere sahip olması gerektmediğinden basit nesneler için optimizasyon gibi avantajlar sağlaması olarak görüyorum.

Bu durumun dezavantajı olarakda insanların bunları bilmesi gerektiğini ve dilin öğrenilmesi zorlaştığı olarak düşünüyorum.

Aslında düşününce C++ bu ayrımı yapmıyor gözükse bile aslında POD türleri yok efendim Trivial türler yok Aggragate türlere sağladığı ek özelliklerle yapıyor gibi(Özür dilerim türkçelerini bilmiyorum).<https://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special >.

O açıdan düşününce aslında her programcının bilmesi gerektiği şeyleri programcının yüzüne vurmak gibi değerlendirilebilir D ve C# 'ın yaptığı. C++ sinsi sinsi yapıyor ama farkına varmadan yanlışa sevk edebiliyor.

Erdemdem .

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

August 22, 2018

C++ olanaklarının temelinde C'ye bağlılık vardır. Zaten ilk C++ derleyicisi olan cfront da tam bir derleyici değil, C++'tan C'ye çeviren bir programdı; asıl derleme arka planda çağrılan bir C derleyicisi ile halledilirdi. Sınıflarla yapıların o yüzden aynıydılar. C++ zamanla karmaşıklaştıkça bu olanaksızlaştı; yani, bazı olanaklar C'ye çevrilemeyecek hale geldi. (Hangileri olduğunu hatırlamıyorum.)

C++'taki gibi değer türleri nesne yönelimli programlamada kullanıldıklarında "slicing" denen bir sorunla karşılaşılır. Referans türleri bu soruna sahip olmadıklarından NYP'ye daha uygundurlar. (Geçen gün izlediğim bir sunumda Bjarne Stroustrup söz alıp slicing'i zamanında C++'ta yasaklamak istediğini, başaramadığını, ama hâlâ yasaklamak istediğini belirtmişti.)

Ali

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

August 23, 2018

Slicing (Dlimleme) Sorunu Konusu: http://ddili.org/forum/thread/1925

Ali Hocam, bu slicing denen sorun neden stack alanında oluşan verilerde meydana geliyor da heap alanında oluşan verilerde olmuyor? Yeni açtığım konuda verdiğim örnek doğrultusunda da gördüğüm, taban sınıfı tür olarak belirleyip, bu taban sınıftan türetilen sınıfların nesnelerinin türüne göre hareket etmek:

BaseClass
|
|-------|
A B

BaseClass bc;
A a; B b;
bc = a;
bc = b;

Aslında şöyle bir bakınca mantıken taban sınıf en az üyeye sahip olan sınıf oluyor genelde. Lakin taban sınıftan türetilen diğer sınıfların nesnelerini en az üyesi bulunan taban sınıfa yerleştirmeye çalışıyoruz, matematiksel olarak yanlış gibi duruyor :) Yani bir nevi evrensel kümeleri, onların alt kümelerinden birine yerleştirmeye çalışıyoruz :)

Anlatmak istediğim şu:
https://s8.postimg.cc/h67s4diw5/img.png

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

August 24, 2018

Alıntı:

>

Stack'tekini işleve adresi olarak geçirirsem dilimleme olmaz; heap'tekinin adresini değil kendisini geçirirsem dilimleme olur.

Benim sorum da aslında bu; niçin adres ve değer farkıyla bu sorun oluşuyor? Yani verinin adresini verince nasıl bir işleme tabi tutuluyor da verinin değer olarak verilmesinde gerçekleşen işlemden farklı oluyor?
Biraz konu dışına çıkacak ama bu konuyla alakalı olduğu için soruyorum: Ben belleğin stack ve heap alanlarının teoride ne olduklarını biliyorum ama sanırım ben olayı yanlış anlamışım, ben şöyle biliyorum: Bellek fiziki olarak gerçekte stack ve heap olarak isimlendirilen iki farklı alana sahip. Lakin bu konuyla alakalı yazıları(nızı) okuduktan sonra sanki yanlış bildiğimi ve gerçekte stack ve heap'in işletim sistemi (ya da belki derleyici - bağlayıcı) tarafından belleğe farklı şekillerde müdahale etme yöntemi olduğunu algıladım. Yani tam olarak bu stack ve heap dediğimiz bellek türleri aslında sadece teorik midir yoksa fiziksel midir? Bunları yapan işletim sistemi mi yoksa derleyici - bağlayıcı (linker) mı? Teşekkürler.

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

August 24, 2018

Dilimleme değer olarak kopyalanırken oluşuyor. O yüzden, stack ve heap arasında fark yok. Stack'tekini işleve adresi olarak geçirirsem dilimleme olmaz; heap'tekinin adresini değil kendisini geçirirsem dilimleme olur.

Her alt sınıf taban sınıfı içerdiğinden, dilimlendiğinde salt alt sınıf kalıyor; taban sınıfın getirdikleri dilimlenip atılıyor.

Ali

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

August 25, 2018

Adres, yalnızca bir gösterge: 64 (veya 32) bitlik bir tamsayı değer. Öyle bir değer geçirirken tam olarak nasıl bir türün adresi olduğu konuyu hiç değiştirmiyor. Gönderen alt tür nesnesinin adresini göndermiş olabilir ve alan da üst tür nesnesinin adresiymiş gibi Kullanır ve hiçbir sorun oluşmaz. Çünkü alt tür zaten o üst türdendir.

Değer olarak gönderildiğinde ise geçici bir nesne oluşur. O geçici nesnenin büyüklüğü yalnızca üst tür kadar olduğundan alt türün içerdiği üst tür parçası kopyalanır. Buna dilimleme (sorunu) denir. Stroustrup bunu yasaklamak istemiş ama karşı çıkanlar olduğu için mecbur kalmış ama hâlâ yasaklamak istediğini söylüyor.

Alıntı:

>

stack ve heap dediğimiz bellek türleri

Stack ve heap arasında fiziksel bir fark yok. Stack, mikro işlemcinin sunduğu yazmaçlardan (RSP - stack pointer register) birisiyle hallediliyor. Her işletim dizisinin (thread) kendisine ait tek RSP değeri oluyor. Program başlatıldığında bu değeri programı başlatan ortam belirliyor. (Herhalde işletim sistemidir ama shell de olabilir; emin değilim.)

Derleyici, geçici ve yerel değişkenlerin ve parametrelerin yerlerini RSP'nin değerini gerektiği kadar değiştirerek ayarlıyor. Örneğin, 4 baytlık bir yerel değişkenin yerini "RSP-4 adresinde" diye belirliyor. Sonra, bir işlev çağıracakken RSP=RSP-4 yapıyor ve o işlevi bu yeni RSP değeri ile çağırıyor. Assembly çıktılarına bakarak ve RSP'ye odaklanarak neler olduğunu anlayabilirsin.

Ali

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