Kelas Penyimpanan dalam C++

Hai teman-teman pemrogram, hari ini kita akan melakukan perjalanan menarik melalui dunia kelas penyimpanan dalam C++. Jangan khawatir jika Anda baru belajar pemrograman; saya akan menjadi panduan ramah Anda, menjelaskan segala sesuatunya secara bertahap. Mari kita masuk ke dalamnya!

C++ Storage Classes

Apa Itu Kelas Penyimpanan?

Sebelum kita masuk ke hal-hal khusus, mari kita pahami apa itu kelas penyimpanan. Dalam C++, kelas penyimpanan menentukan cakupan (kepentingan) dan masa hidup variabel dan fungsi dalam program. Mereka memberitahu kompilator bagaimana menyimpan variabel, apakah dapat diakses dari file lain, dan berapa lama itu harus ada dalam memori.

Sekarang, mari kita telusuri setiap kelas penyimpanan secara detil.

Kelas Penyimpanan auto

Kata kunci auto dalam C++ telah berubah maknanya sepanjang waktu. Dalam C++ modern (C++11 dan seterusnya), itu digunakan untuk inferensi tipe. Namun, dalam versi lama, itu adalah spesifikator kelas penyimpanan.

Penggunaan Lama (sebelum C++11):

int main() {
auto int x = 5;  // Setara dengan: int x = 5;
return 0;
}

Dalam penggunaan lama ini, auto secara eksplisit mendeklarasikan variabel dengan durasi penyimpanan otomatis. Namun, ini adalah default untuk variabel lokal, jadi jarang digunakan.

Penggunaan Modern (C++11 dan seterusnya):

int main() {
auto x = 5;  // x diasumsikan sebagai int
auto y = 3.14;  // y diasumsikan sebagai double
auto z = "Hello";  // z diasumsikan sebagai const char*
return 0;
}

Dalam C++ modern, auto membiarkan kompilator mendifeksi tipe variabel berdasarkan inisialisator. Ini sangat berguna untuk tipe kompleks atau saat tipe mungkin berubah di masa mendatang.

Kelas Penyimpanan register

Kata kunci register adalah hint kepada kompilator bahwa variabel ini akan digunakan secara berat dan sebaiknya disimpan dalam register CPU untuk akses yang lebih cepat.

#include <iostream>

int main() {
register int counter = 0;

for(int i = 0; i < 1000000; i++) {
counter++;
}

std::cout << "Counter: " << counter << std::endl;
return 0;
}

Dalam contoh ini, kita mengajukan kepada kompilator bahwa counter sebaiknya disimpan dalam register. Namun, kompilator modern biasanya cukup pintar untuk membuat optimisasi ini sendiri, jadi register jarang digunakan dalam praktek.

Kelas Penyimpanan static

Kata kunci static memiliki makna yang berbeda tergantung dimana itu digunakan:

1. Variabel Statik Lokal

#include <iostream>

void countCalls() {
static int calls = 0;
calls++;
std::cout << "Fungsi ini telah dipanggil " << calls << " kali." << std::endl;
}

int main() {
for(int i = 0; i < 5; i++) {
countCalls();
}
return 0;
}

Dalam contoh ini, calls diinisialisasi hanya sekali dan menahan nilainya antara pemanggilan fungsi. Outputnya akan seperti ini:

Fungsi ini telah dipanggil 1 kali.
Fungsi ini telah dipanggil 2 kali.
Fungsi ini telah dipanggil 3 kali.
Fungsi ini telah dipanggil 4 kali.
Fungsi ini telah dipanggil 5 kali.

2. Anggota Statik Kelas

class MyClass {
public:
static int objectCount;

MyClass() {
objectCount++;
}
};

int MyClass::objectCount = 0;

int main() {
MyClass obj1;
MyClass obj2;
MyClass obj3;

std::cout << "Jumlah objek yang diciptakan: " << MyClass::objectCount << std::endl;
return 0;
}

Di sini, objectCount disembagi antara semua instance dari MyClass. Outputnya akan seperti ini:

Jumlah objek yang diciptakan: 3

Kelas Penyimpanan extern

Kata kunci extern digunakan untuk mendeklarasikan variabel atau fungsi global dalam file lain.

File: globals.cpp

int globalVar = 10;

File: main.cpp

#include <iostream>

extern int globalVar;  // Deklarasi globalVar

int main() {
std::cout << "Nilai variabel global: " << globalVar << std::endl;
return 0;
}

Dalam contoh ini, globalVar didefinisikan dalam globals.cpp dan dideklarasikan sebagai extern dalam main.cpp. Ini memungkinkan main.cpp untuk menggunakan variabel yang didefinisikan dalam file lain.

Kelas Penyimpanan mutable

Kata kunci mutable memungkinkan anggota sebuah objek const untuk dimodifikasi.

class Person {
public:
Person(int age) : age(age), cacheValid(false) {}

int getAge() const {
if (!cacheValid) {
cachedAge = heavyComputation();
cacheValid = true;
}
return cachedAge;
}

private:
int age;
mutable int cachedAge;
mutable bool cacheValid;

int heavyComputation() const {
// Simulasi komputasi berat
return age;
}
};

int main() {
const Person p(30);
std::cout << p.getAge() << std::endl;  // Ini diperbolehkan
return 0;
}

Dalam contoh ini, meskipun p adalah const, kita dapat memodifikasi cachedAge dan cacheValid karena mereka ditandai sebagai mutable.

Ringkasan

Mari kita ringkaskan kelas penyimpanan yang kita pelajari dalam tabel praktis:

Kelas Penyimpanan Tujuan
auto Inferensi tipe (C++ modern)
register Hint untuk akses cepat (jarang digunakan)
static Menyimpan nilai antara pemanggilan fungsi atau disembagi antara instance kelas
extern Mendeklarasikan variabel atau fungsi dari file lain
mutable Memungkinkan modifikasi dalam objek const

Ingat, memahami kelas penyimpanan sangat penting untuk mengelola memori secara efisien dan mengendalikan cakupan variabel Anda. Sebagai Anda terus melanjutkan perjalanan C++ Anda, Anda akan menemukan konsep ini menjadi hal yang biasa. Selamat coding!

Credits: Image by storyset