array sınıf şablonu

STL’in array sınıf şablonu  C dizilerini sarmalayarak bu dizilere STL kaplarının (container) arayüzünü kazandırır. array sınıf şablonu ile diziler ek bir maliyet olmadan daha güvenli, daha kolay bir biçimde ve STL’in diğer bileşenleriyle uyumlu olarak kullanılabilir.

Şablon temelli array sınıfı C++’ın standart kütüphanesine TR1 eklentileriyle alınmış ve C++11 ile tamamen standart hale getirilmiştir. Bir array nesnesi belirli bir türden ve belirli sayıda öğeye sahip bir diziyi temsil eder. Dizinin öğe sayısı sabittir. Dizi üzerinde ekleme ve silme işlemleri yapılamaz.
Bu sınıfın kulanılması için array başlık dosyasının kaynak koda eklenmesi gerekir:

Sınıfın şablon tanımı <array> başlık dosyasında ve std isim alanı içindedir:

Bir array sınıf nesnesinin taşıyacağı öğeler herhangi bir türden olabilir. Şablonun sabit parametresi (non type parameter) olan N temsil edilen dizinin boyutunu belirlemektedir. Bu boyut değeri array nesnesinin ömrü süresince sabit olarak kalacaktır. Bir başka deyişle array sınıfınının

üye işlevinin geri dönüş değeri her zaman şablon sabit parametresi olan N değeridir.
array kapları için allocator desteği bulunmamaktadır.

array sınıf nesnesinin taşıdığı öğeler, içsel olarak C tarzı bir dizide tutulduklarından bellekte sıralı ve ardışık şekilde yer alırlar. Sırası yani konumu bilinen bir öğeye sabit zamanda (constant time) erişilebilir.
array kabı random access iterator kategorisinde adımlayıcı (iterator) sağladığından STL’in tüm algoritmaları array kabı için de kullanılabilir.
Sınıfın kodlarında dinamik bellek yönetimi kullanılmadığından ve yeniden bellek edinimi (reallocation) söz konusu olmadığından bazı temel işlemler vector sınıfına göre daha hızlı bir şekilde yapılır.

İlk değer verme açısından array sınıfı STL’in diğer kap sınıflarına göre farklı özellikler taşır. Diğer STL kaplarından farklı olarak varsayılan kurucu işlev boş bir kap yaratmaz. Çünkü kapta tutulan öğe sayısı şablonun sabit parametresi tarafından derleme zamanında belirlenmektedir. array sınıf nesnesine ilk değer verilmez ise doğal türlerden (primitive) öğeler çöp değerlerle hayata başlar.

Boş bir ilk değer verme listesi ile öğelerin 0 değerleriyle hayata başlamaları sağlanabilir:

Kodun geçerli olması için ilk değer listesindeki ifadelerin array öğelerinin türünden ya da bu türe otomatik olarak dönüştürülecek türlerden olması gerekir. İlk değer verme listesinde kullanılan öğe sayısı array nesnesinin öğe sayısından daha az ise doğal türlerden ilkdeğer verilmemiş tüm öğeler 0 değeri ile hayata başlar. Öğe sayısından daha fazla sayıda ilk değer vericinin kullanılması geçersizdir.
array sınıfı bir bileşik (aggregate) tür olduğundan tüm veri öğeleri sınıfın public bölümündedir. Ancak öğe isimleri standart olarak belirlenmemiştir. Öğelere isimleriyle erişmek geçerli olsa da bu durumda bir taşınabilirlik söz konusu değildir.

Standart move işleviyle kopyalama yerine taşıma semantiği sağlanabilir:

Öğe sayısı 0 olan bir array nesnesi oluşturabilir.

Bu durumda sınıfın begin ve end işlevleri aynı adımlayıcı değerlerini döndürür. Boş bir array nesnesi için yapılacak

gibi bir çağrı geçerli ama etkisiz bir koddur. Öğe sayısının 0 olması durumunda sınıfın front , back ve [] işlevlerinin çağrılması tanımsız davranış oluşturur.

Sınıfın varsayılan kurucu işlevi  varsayılan şekilde hayata getirilmiş N tane öğeye sahip bir array nesnesi oluşturur. Dizi öğelerinin doğal türlerden olması durumunda öğeler çöp değerlerle hayata gelir:

Kopyalayan kurucu işlev ile aynı türden bir başka array nesnesinin öğelerini kopyalayarak bir array nesnesi oluşturabiliriz:

array sınıfının aşağıdaki işlevleriyle bir array nesnesine atama yapılabilir:

Atamaya yönelik tüm işlevler array nesnesinde tutulan öğelerin kendi atama işlevlerini kullanır.
C++11 standartlarıyla sınıfa taşıma atama işlevi de eklenmiştir. Diğer tüm STL kaplarında olduğu gibi array sınıfının da swap işlemi vardır. Yani aynı türden iki array nesnesi swap işleviyle takas edilebilir. Ancak bu durumda takas edilen veri elemanı olan göstericiler değil array nesnesinin tuttuğu öğelerin kendileridir. Bu işlem sabit zaman karmaşıklığında değil doğrusal karmaşıklıktadır. Takas işleminden sonra array nesnesinin tuttuğu öğeleri gösteren göstericiler ya da referanslar halen geçerli olmakla birlikte öğeler değişmiştir. Yalnızca aynı türden olan array nesneleri swap işleviyle takas edilebilir. Türlerin aynı olması şablon tür ve sabit parametrelerinin aynı olması gerektiği anlamına gelir. İki array nesnesi global swap şablonundan özelleştirilmiş bir şablonla da takas edilebilir.
Sınıfın fill üye işleviyle array nesnesinin tüm öğelerine tek bir işlev çağrısıyla aynı değer yerleştirilebilir:

array sınıfın hiçbir üye şablon işlevi (member template) olmadığından array sınıf şablonundan üretilmiş farklı sınıflar arasında otomatik tür dönüşümü yoktur:

Bir array nesnesinin tuttuğu öğelere erişmenin birçok yolu vardır:
aralık tabanlı for döngüleri (range based for loops) ile
adımlayıcı yoluyla
sınıfın [ ] ve at işlevleriyle
tuple arayüzünde bulunan get işlev şablonu ile.

Aralık tabanlı for döngüleri C++11 ile getirilen yeni araçlardan biridir.  Bu döngü yapısını C dizileri ve tüm STL kapları için kullanabiliriz: Aşağıdaki kodu inceleyin:

Sınıfın at ve [ ] operatör işlevleri array nesnesinin tuttuğu öğelere erişim sağlar. İşlevlerin tanımında const yüklemesi kullanılmıştır.

C dizilerinde olduğu gibi ilk öğenin indisi 0’dır. Son öğenin indisi size() – 1 değeridir. Tüm STL kaplarında olduğu gibi sınıfın size üye işlevi kapta tutulan öğe sayısını döndürmektedir. array kabında tutulan öğe sayısı array sınıf şablonunun sabit parametresidir.
Bildirimlerden de görüldüğü gibi her iki işlev de indisi verilen öğeye referans yoluyla erişim sağlar. operator[] işlevine geçersiz bir indis değerinin geçilmesi çalışma zamanı hatasıdır. Bu durumda bir hata nesnesi (exception) gönderilmez. Ancak at üye işlevine geçersiz bir indis değerinin geçilmesi durumunda standart kütüphanenin exception sınıfı hiyerarşisindeki logic_error sınıfından türetilmiş out_or_range sınıfı türünden bir hata nesnesi gönderilir:

Sınıfın front ve back işlevleri array nesnesini tuttuğu ilk ve son öğelere referans yoluyla erişim sağlar:

Aşağıdaki kodda front ve back işlevleriyle a isimli array nesnesinin ilk ve son öğelerine erişiliyor:

array sınıfının adımlayıcıları random access iterator kategorisindedir. Yani bu adımlayıcılar doğal göstericilerin sahip olduğu tüm arayüze destek sağlamaktadır. Bu da tüm STL algoritmalarının bir array nesnesi aralığı üzerinde koşturulabileceği anlamına gelir.

Adımlayıcıların gerçek türünün ne olacağı derleyiciye bağlıdır. Derleyiciler çoğunlukla adımlayıcı olarak gerçek göstericiler kullanıyor olmakla birlikte, tam bir taşınabilirlik sağlamak amacıyla buna güvenilerek kod yazılmamalıdır. Bazı derleyiciler daha güvenli bir erişim sağlama amacıyla adımlayıcı türünün gerçekleştirimini yardımcı bir sınıf ile yapıyor olabilirler.

Diğer STL kaplarında olduğu gibi array kabının da adımlayıcı döndüren aşağıdaki üye işlevleri vardır:

C++11 ile birlikte tüm STL kapları ve C dizileri için adımlayıcı veren global işlevlerin de tanımlandığını hatırlayalım.

array sınıfı tuple sınıfının arayüzünü de destekler:

vector sınıfında olduğu gibi array kabı için de C++ standartları öğelerin bellekte ardışık yerleştirilme şartını getirmiştir. Yani a bir array nesnesi ve idx de geçerli bir indis olmak olmak üzere

ifadesi ile

ifadesi aynı anlamdadır. Bu garantinin anlamı şudur: Bir C dizisi kullanabileceğiniz her yerde bir array nesnesi kullanabilirsiniz. Örneğin bir array nesnesi bir yazı tutması için bile kullanılabilir:

Kuşkusuz array nesnesinin yukarıdaki örnekte olduğu gibi göstericiler yoluyla kullanımında, dizinin yeteri kadar büyük olması ve yazının sonunda sonlandırıcı karakterin bulunması programcının sorumluluğundadır. Var olan bir C kütüphanesi ile kullanmak amacıyla array ya da vector sınıflarının data isimli üye işlevi kullanılarak arka planda kullanılan sürekli bellek alanının adresi elde edilebilir.

aynı türden array nesneleri global karşılaştırma işlevleriyle karşılaştırılabilirler.

array sınıfı çalışma zamanı hatalarının kontrolu için kayda değer bir destek sağlamaz. Yalnızca sınıfın at üye işlevi içinden bir hata nesnesi gönderilebilir. Bu işlev operatör[ ] işlevinin daha güvenli bir biçimidir. array nesnesinin tuttuğu öğelerin üye işlevlerinden hata nesnesi gönderilmesi durumunda sınıfın kodları bir hata yakalama girişiminde bulunmaz. Özellikle swap işlevinde böyle bir risk söz konusu olabilir. swap işlevi işini yapabilmek için array nesnesinde tutulan öğelerin kendi swap işlevini çağıracağından bu durumda hata nesnesi gönderilmesi olasılığı vardır.

Necati Ergin

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

Bunlar da ilginizi çekebilir

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Kod Eklemek İçin Okuyun