C++ Depolama Sınıfları

Depolama sınıfları, değişkenlerin veya fonksiyonların yaşam süresini ve kapsam alanını tanımlamada kullanılır. C++ programlama dilinde kullanılan depolama sınıfları şunlardır:
  • auto
  • extern
  • static
  • register
  • mutable

auto

auto depolama sınıfı, tüm local değişkenler için varsayılan depolama sınıfıdır. Kısacası kod bloğu içinde tanımlanmış değişkenler, varsayılan olarak auto depolama sınıfına girerler. Bir fonksiyon içerisinde tanımlanmış değişken otomatik olarak auto depolama sınıfına girdiği için auto diye tekrardan tanımlamamıza gerek yoktur. Kapsam alanı tanımlandığı kod bloğudur. Yaşam süreleri ise tanımlanmış olduğu blokların çalıştığı süredir.
int example(){
  auto int y;      //local değişken bildirimi(auto)
  int s;           //local değişken bildirimi(auto) 
}
Yukarıdaki example fonksiyonu içinde tanımlanmış y değişkeni yalnızca tanımlandığı fonksiyon içerisinde kullanılabilir. Bu fonksiyonda y ile s değişkeni arasında hiçbir fark yoktur. Her ikisinin depolama sınıfı da auto. y değişkenini bildirirken auto yazmamıza gerek yoktu.

extern

Program birden çok dosyadan oluşabilir. global bir değişkene programın başka dosyalarından ulaşmak için yapılması gereken global değişkenin önüne extern eklemektir. Bu sayede başka bir dosyada kullanılan değişken, global tanımlandığı dosyadaki adresi kullanır. Bir örnek yapalım.

dosya.cpp
int x = 0;
dosya.cpp dosyasında x global değişken olarak tanımlanmış oldu. Şimdi ise x global değişkenini başlık dosyamız olan dosya.hpp dosyasında extern olarak bildirelim.

dosya.hpp
extern int x;
Diğer program dosyamız olan dosya2.cpp dosyasında x global değişkenini kullanmak için başlık dosyamızı include etmeliyiz.

dosya2.hpp
#include "dosya.hpp"

int fonk(){
 x = 12;
 return x;
}
extern depo sınıfının kullanım süresi(lifetime) programın başlangıcından sonuna kadardır.

static

Static olarak tanımlanan bir değişken programın başlatılıp sonlanmasına kadar varolur. Eğer bir fonksiyonun içinde static değişken tanımlarsanız fonksiyonun çalışması bitse dahi static değişken auto gibi yok olmaz, varlığını korur. Ancak kapsam alanı(local) gereği değişkenin tanımlandığı blok dışında değişkene erişilemez. Bu yüzden değişkenin tanımlandığı fonksiyonun çalışması bittiği anda static değişkenin de işi biter. Fakat sahip olduğu adresi ve değeri programın bitimine kadar korur. Static değişken fonksiyonların dışında da tanımlanabilir, ancak sadece tanımlandığı program dosyasından değişkene erişilebilir. extern ile nitelenen değişkenlerde olduğu gibi başka program dosyalarından static değişkene erişim mümkün değildir. static değikenler tanımlandığında varsayılan olarak 0 değerini alırlar. Şimdi açıklayıcı bir örnek yapalım.
#include <iostream>

using namespace std;

//static global değişken
static int m = 1; 


void example(){
         //static local değişken
         static int k = 5;
 
         cout << "k : " << k-- << "\t";
         cout << "m : " << m++ << endl;
}

int main(){
         while(m<=5){
            example();
         }
         return 0;
}
Programı çalıştırdığımızda konsol ekranında aşağıdaki sonuç çıkacak.
k : 5   m : 1
k : 4   m : 2
k : 3   m : 3
k : 2   m : 4
k : 1   m : 5
Eğer her iki değişkenin önüne de static eklemeseydik aşağıdaki sonuçla karşılaşacaktık.
k : 5   m : 1
k : 5   m : 2
k : 5   m : 3
k : 5   m : 4
k : 5   m : 5
Static tanımlıyken her iki değişkenimiz de programın çalışma süresi boyunca adres ve değerlerini korur. Fakat static tanımlamaya kaldırırsak değişkenlerimi otomatik olarak auto tanımlı olurlar. Bu sebeple yerel değişken olan k auto tanımlı olduğu için yaşam süresi fonksiyonun çalışma süresi kadar olduğu için adresini ve değerini koruyamaz. Program her döngüde k değerini 5 olarak gösterir. m değişkeninde değişiklik olmamasının sebebi ise global değişken olmasıdır kısacası static kaldırılsa bile m değişkeninin yaşam süresi aynı kalır.

register

Değişkenin register ile tanımlanması, derleyiciye değişkenin RAM içerisinde değil register içerisinde depolanacağını bildirmektir. Fakat her ne kadar değişken register ile tanımlanmış olsada register içerisine kayıt edileceği kesin değildir. Kısacası o anki donanımın durumuna bağlıdır. Eğer CPU içerisinde değişken için boş ve uygun olan bir register yok ise değişken RAM içerisinde depolanır. Register kullanımının nedeni program içerisinde fazlasıyla kullanılan değişkene daha hızlı erişebilmektir. Örneğin bu değişken bir döngü içerisinde kullanılan sayaç olabilir. Değişken ancak bir blok içerisinde register olarak tanımlanabilir.
register int i;

mutable

Bir sınıf yapısı olsun ve bu sınıf yapısından değiştirilemez olarak const tanımlı nesne üretelim. Artık bu sınıf nesnesinin üye değerleri değiştirilemez. Fakat sınıf üyesinden herhangi birini mutable olarak tanımlarsak, bu sınıf üyesinin değeri değiştirilebilir. Aşağıdaki kod örneğini ve ekran çıktısını incelersek durumu daha iyi kavrayabiliriz.
#include <iostream>

using namespace std;

class example{
 mutable int num1;
 int num2;
 
 public:
  example(int n1, int n2)
  {
   num1 = n1;
   num2 = n2;
  }
  
  void add(int n1, int n2) const
  {
   num1 = n1;
   num1 = n2;
  }
  
  void print() const
  {
   cout << num1 << endl;
   cout << num2 << endl;
  }
};

int main(){
 const example ex(342,384);
 ex.print();
 cout << "---\n";
 ex.add(78,34);
 ex.print();
 return 0;
}
Ekran Çıktısı:
342
384
---
34
384
Görüldüğü num1 değeri mutable tanımlı olduğu için değeri değişti, ancak num2 değeri değişmedi.

Hiç yorum yok:

Yorum Gönderme