İndeks erişim operatörü operator[], kullanıcı tanımlı kapsayıcı nesnelerinin (örneğin, diziler gibi) indeksleme sözdizimini sağlamak için C++'da aşırı yüklenebilir bir operatördür.
Konu ile ilgili geçmiş:
C dilinde ve sonrasında C++'da, [] operatörü, dizinin elemanlarına indeks ile hızlı ve kolay erişim sağlıyordu. Ancak, kapsayıcı sınıfların popülaritesi arttığında, aynı sözdizimini kullanıcı tanımlı veri türlerine taşımak gerekiyor.
Sorun:
İndeks erişim operatörlerini doğru bir şekilde tasarlamak, sabitlik, sınır ötesi (out-of-bounds) güvenliği, dönen değer seçimleri ve referans veya işaretçinin geçerliliğiyle ilgili sorunlarla bağlantılıdır.
Çözüm:
C++'da sınıflar için operator[] aşırı yüklenebilir, böylece indeks ile elemanlara erişim sağlanır ve "dizi gibi davranış" gerçekleştirilir. Hem normal (sabit olmayan nesneler için) hem de sabit (sabit nesneler için) operatörün iki versiyonu uygulanmalıdır.
Kod örneği:
class MyArray { int data[10]; public: int& operator[](size_t index) { return data[index]; } const int& operator[](size_t index) const { return data[index]; } }; MyArray arr; arr[3] = 42; // Tamam const MyArray& const_arr = arr; int val = const_arr[3]; // Tamam
Ana özellikler:
.at()'ın aksine)operator[]'den referans döndürmek zorunlu mu?
Hayır, ancak değer döndürürseniz arr[i] = x; sözdizimi çalışmayacaktır (kopya oluşturursunuz, atama yapmazsınız). Kontenerin alışılmış semantiğini desteklemek için genellikle referans döndürülür. Şayet değer döndürülürse, elemana yazma işlemi mümkün olmayacaktır:
int operator[](size_t idx); // arr[2] = 10; derleme hatası verir
operator[] sınırları kontrol etmeli mi?
Standart bunu gerektirmez. Klasik operator[] (örneğin std::vector'da) bu tür kontroller yapmaz. Kontroller için standart kapsayıcılar, indeksleme aralığını aştığında istisna fırlatan ayrı bir .at() yöntemini tanıtır.
operator[] sabit bir yöntem olabilir mi?
Hayır, eğer sabit olmayan bir referans döndürüyorsanız. Ancak operator[]'yi sabit ve sabit olmayan nesneler için aşırı yüklemek gereklidir, böylece kapsayıcı sezgisel ve güvenli bir şekilde çalışır.
Genç bir geliştirici yalnızca sabit olmayan bir versiyonunu uygulayıp, değer döndüren operator[]'yi gerçekleştirdi. Sonuç olarak, kapsayıcıya sabit referansla erişim mümkün olmadı ve tüm yazma girişimleri garip bir şekilde çalıştı — değerler tutulmadı.
Artılar:
Eksiler:
MyArray kapsayıcısında her iki operator[] versiyonu uygulanmış ve referans döndürülmüş. Gerekirse sınır kontrolü ile birlikte at() yöntemi eklenmiştir.
Artılar:
Eksiler: