adreslerin karşılaştırılması ve C++

Dinamik tür kavramına sahip C++ dilinde bir nesne birden fazla geçerli adrese sahip olabilir.  Adreslerin karşılaştırılması adreslerden ziyade nesnelerin kimliği (identity) ile ilgili. Aşağıdaki koda bakalım:

Yukarıdaki sınıf hiyerarşisinde ObservedBlob sınıfı, hem Shape sınıfından hem de Subject sınıfından çoklu türetme (multiple inheritance) yoluyla elde ediliyor. Her iki taban sınıftan da public türetmesi yapıldığından ObservedBlob sınıfından hem Shape sınıfına hem de Subject sınıfına doğal dönüşüm var:

Yukarı doğru yapılan bu dönüşümlerin (upcasting) varlığı ObservedBlob türünden bir adresin her iki taban sınıf türünden adreslerle karşılaştırılması olanağı sağlıyor:

Bu adresler fiziksel olarak farklı olabilse de her iki karşılaştırma da eşitlikle sonuçlanacak. new işleciyle hayata getirilen ve pointer değişkenlerimizin gösterdiği ObservedBlob nesnesinin bellekteki yerleşimine ilişkin iki ayrı yapıyı düşünelim:

 

 

 

 

 

 

 

Yerleşim 1’de shape_ptr ve subject_ptr gösterici değişkenleri bütünü oluşturan ObservedBlob nesnesi içindeki Shape ve Subject türünden olan taban sınıf nesnelerini gösteriyorlar.  Bu nesnelerin fiziksel adresleri ObservedBlob nesnesinin adresinden farklı.

Yerleşim-2’de ise, ObservedBlob nesnesinin adresi fiziksel olarak Shape taban sınıf nesnesinin adresi ile aynı. Yani ob_ptr ve shape_ptr pointer değişkenleri aynı adres değerini tutuyorlar. Her iki yerleşim biçiminde de ob_ptr, shape_ptr ve subject_ptr göstericileri aynı ObservedBlob nesnesine ilişkinler. Bu durumda derleyicinin eşitlik karşılaştırmasına ilişkin ürettiği kod true değer üretecek. Ancak Shape ve Subject sınıfları arasında bir kalıtım ilişkisi olmadığından aşağıdaki gibi bir karşılaştırma işlemi geçerli olmayacaktı:

Peki derleyici

karşılaştırması için nasıl bir kod üretiyor dersiniz? Bu karşılaştırmaya ilişkin sözde (pseudo) kod şöyle gösterilebilir:

Derleyici karşılaştırmaya ilişkin adresleri bir ofset ile yani bir toplama değeri ile ayarlıyor. Burada delta değeri ObservedBlob nesnesi içindeki Subject taban sınıf nesnesinin ofseti. Yani eğer her iki pointer değişken de nullptr değerinde ise karşılaştırmada true değeri elde edilecek. Aksi halde karşılaştırmaya ob_ptr göstericisinin değeri olan adres değil de ob_ptr göstericisinin gösterdiği nesne içindeki Subject nesnesinin adresi sokulacak.

Kıssadan hisse şu: Bu tür karşılaştırmalarda tür bilgisi kesinlikle kaybedilmemeli. void göstericilerin kullanımı burada ciddi bir tuzak oluşturuyor:

Eğer adrese ilişkin tür bilgisini göz ardı ederek bu adresi bir void göstericiye kopyalarsak, derleyici doğal olarak fiziksel adresi kopyalayacak bir kod üretecek.

Bu yazı Stephan C. Dewhurst’un bir makalesinin serbest çevirisidir.

Share

Necati Ergin

C ve Sistem Programcıları Derneğinde eğitmen olarak çalışıyor.

Bunlar da ilginizi çekebilir

Kod Eklemek İçin Okuyun