Anasayfa / C++ / C++ Sabitler (const) Nedir ve Nasıl Kullanılır?

C++ Sabitler (const) Nedir ve Nasıl Kullanılır?

Yazılım geliştirme sürecinde, programın çalışması boyunca değerinin hiçbir zaman değişmemesini istediğimiz verilere ihtiyaç duyarız. Örneğin; Pi sayısı, haftanın gün sayısı veya bir dizinin maksimum kapasitesi programın hiçbir aşamasında değiştirilmemelidir. C++ programlama dilinde, programın çalışması sırasında değiştirilemeyen bu sabit değerleri (constants) oluşturmak için const anahtar kelimesi kullanılır.

Bu kapsamlı rehberde, C++ dilinde sabitlerin (const) ne olduğunu, nasıl tanımlandığını, işaretçilerle (pointers) ve sınıflarla (classes) nasıl kullanıldığını adım adım ve bol örneklerle inceleyeceğiz.

1. C++’ta const Nedir ve Nasıl Tanımlanır?

C++ dilinde bir değişkenin önüne const niteleyicisi (modifier) getirildiğinde, o değişkenin değeri program boyunca sadece okunabilir (read-only) hale gelir ve hiçbir şekilde değiştirilemez.

Önemli Bir Kural: C++ dilinde bir sabit (const) tanımlandığı anda mutlaka bir ilk değerle başlatılmak (initialize edilmek) zorunludur. Eski C dilinde bu zorunlu değildi, ancak C++ bu konuda çok daha katıdır.

Örnek Kullanım:

#include <iostream>
using namespace std;

int main() {
    const int MAX_KULLANICI = 100; // Tanımlandığı anda değer atandı

    // MAX_KULLANICI = 150; // HATA! const bir değişkene yeni değer atanamaz.

    cout << "Maksimum Kullanıcı Sayısı: " << MAX_KULLANICI << endl;
    return 0;
}

2. Neden #define Yerine const Kullanmalıyız?

Eski C programcıları sabit tanımlamak için genellikle #define ön işlemci (preprocessor) direktifini kullanırlardı. Ancak C++’ta #define yerine const kullanılması şiddetle tavsiye edilir. Bunun en büyük nedeni tip güvenliğidir (type safety). #define ile oluşturulan sabitlerin bir veri tipi yoktur; oysa const kullandığımızda sabitin bir veri tipi (int, float, char vb.) olduğunu derleyiciye açıkça bildirmiş oluruz.

Ayrıca kapsam (scope) kuralları açısından da farklılıklar vardır. C++ dilinde const değişkenler varsayılan olarak iç bağlantıya (internal linkage) sahiptir, yani yalnızca tanımlandıkları dosyada geçerlidirler. Oysa C dilinde const değerler küresel (global) özellik taşır. C++’ta bir sabiti dış dosyalardan erişilebilir yapmak istiyorsanız açıkça extern const şeklinde tanımlamanız gerekir.

extern const int total = 100; // Başka dosyalardan da erişilebilir

3. İşaretçiler (Pointers) ve const Kullanımı

C++’ta const kavramının en çok kafa karıştıran ama en güçlü olduğu alanlardan biri işaretçilerdir (pointers). const anahtar kelimesinin yıldız (*) işaretinin sağına mı yoksa soluna mı yazıldığına göre anlam tamamen değişir.

a) Sabite İşaret Eden İşaretçi (Pointer to a Constant): İşaretçinin kendisi değiştirilebilir (başka bir adresi gösterebilir), ancak işaret ettiği değer değiştirilemez.

int m = 10;
int n = 20;
int const *ptr2 = &m; // ptr2, m'nin değerini değiştiremez

// *ptr2 = 15; // HATA! Değer değiştirilemez.
ptr2 = &n;     // GEÇERLİ! İşaretçi başka bir adresi gösterebilir.

b) Sabit İşaretçi (Constant Pointer): İşaretçinin gösterdiği adres sabittir ve değiştirilemez, ancak o adresteki değer değiştirilebilir.

char const *ptr1 = "GOOD"; // Sabit işaretçi örneği
// ptr1 başka bir adresi gösteremez.

c) Sabite İşaret Eden Sabit İşaretçi (Constant Pointer to a Constant): Hem işaretçinin gösterdiği adres hem de o adresteki değer sabittir. Hiçbir şey değiştirilemez.

const char * const cp = "xyz"; // cp'nin adresi de, gösterdiği değer de değiştirilemez

4. Fonksiyon Argümanlarında const (const Arguments)

Fonksiyonlara argüman (parametre) gönderirken, özellikle referans veya işaretçi yoluyla veri iletiyorsak (call by reference), fonksiyonun bu orijinal veriyi yanlışlıkla değiştirmesini engellemek isteyebiliriz. Bu durumlarda fonksiyon parametresi const olarak tanımlanır.

int uzunlukBul(const string &s) {
    // s = "Yeni Metin"; // HATA! const argüman fonksiyon içinde değiştirilemez.
    return s.length();
}

Bu kullanım (const arguments), derleyiciye “bu fonksiyon kendisine gönderilen argümanı değiştirmeyecek” garantisini verir. Bu kuralların ihlal edilmesi durumunda derleyici hata üreterek programcıyı uyarır.

5. Nesne Yönelimli Programlamada (OOP) const Kullanımı

C++, nesne yönelimli bir dil olduğu için const kavramı sınıflar (classes) ve nesneler (objects) üzerinde çok sıkı kurallara sahiptir.

a) Sabit Nesneler (const Objects): Bir sınıf nesnesi const anahtar kelimesi ile oluşturulursa, o nesnenin içindeki hiçbir veri (data member) değiştirilemez.

const matrix X(m, n); // X nesnesi sabittir

Eğer bu nesnenin herhangi bir değerini değiştirmeye çalışırsanız, derleme zamanı (compile-time) hatası alırsınız.

b) Sabit Üye Fonksiyonlar (const Member Functions): Sabit bir nesne (const object), sınıfın içindeki her fonksiyonu çağıramaz. Yalnızca sabit üye fonksiyonları (const member functions) çağırabilir. Bir üye fonksiyonun, sınıfın verilerini değiştirmeyeceğini garanti etmek için fonksiyon deklarasyonunun sonuna const eklenir.

class BankaHesabi {
    double bakiye;
public:
    BankaHesabi(double b) : bakiye(b) {}

    // Bu fonksiyon sınıfın verilerini değiştiremez
    double get_bakiye() const {
        // bakiye = bakiye + 10; // HATA! const fonksiyon veriyi değiştiremez.
        return bakiye;
    }
};

6. Modern C++’a Doğru: constexpr ve Derleme Zamanı Sabitleri

C++ sürekli gelişen bir dildir. C++11 ile hayatımıza giren ve C++23/C++26 standartlarıyla devasa özellikler kazanan constexpr (constant expression), const kavramını bir adım öteye taşımıştır.

constexpr, bir değerin veya fonksiyonun sonucunun sadece sabit olmasını değil, aynı zamanda derleme zamanında (compile-time) hesaplanmasını garanti eder. Modern C++26 standardı ile birlikte artık standart konteynerler (örneğin vektörler veya adaptörler), karmaşık algoritmalar ve hatta istisnalar (exceptions) bile tam anlamıyla constexpr desteklemektedir. Bu, çalışma zamanı (run-time) hatalarını derleme zamanında yakalayarak sistemlerin daha hızlı ve çok daha güvenli olmasını sağlamaktadır.

Sonuç

C++ dilinde const kullanımı, sadece basit bir “değişken kilitleme” aracı değildir. Aynı zamanda yazılım mimarisinde güvenliği sağlayan, fonksiyonların birbirlerinin verilerini bozmasını engelleyen ve modern derleyicilerin kodunuzu optimize etmesine olanak tanıyan devasa bir sözleşmedir (contract). Tip güvenliğine önem veren, belleği verimli ve güvenli kullanmak isteyen her C++ geliştiricisinin const doğruluğunu (const correctness) alışkanlık haline getirmesi gerekir.

Etiketlendi:

Cevap bırakın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir