Sebagian konversi tipe terjadi otomatis — misalnya int ikut menjadi double saat dibandingkan — sebagaimana dibahas pada Chapter Konversi Tipe Data. Namun saat konversi perlu dilakukan secara sadar dan terlihat jelas di kode, kita memakai cast eksplisit. C++ modern menyediakan empat bentuknya: static_cast untuk konversi bermakna antar tipe terkait, dynamic_cast untuk navigasi hierarki class, const_cast untuk menambah atau melepas const, dan reinterpret_cast untuk menafsir ulang bit secara mentah. Pada Chapter ini static_cast kita uji langsung, sementara tiga lainnya dikenalkan sebagai pratinjau karena kebutuhan materinya (class, pointer) menyusul di Section berikutnya.
Mengapa Cast Perlu Eksplisit #
Cast eksplisit adalah pernyataan niat: “ya, konversi ini memang saya mau”. Ada dua keuntungannya. Pertama, pembaca kode langsung melihat titik-titik konversi yang berisiko — misalnya pemotongan nilai saat double menjadi int. Kedua, beberapa konversi tidak akan terjadi sama sekali tanpa cast, misalnya mengubah const atau menafsir ulang pointer; compiler menolaknya demi keamanan dan hanya membuka jalur lewat cast yang tepat.
static_cast: Cast Harian #
Bentuknya static_cast<tipeTujuan>(nilai). Inilah cast yang paling sering dipakai untuk konversi tipe fundamental dan konversi bermakna lainnya.
#include <iostream>
int main() {
double rataRata = 87.6;
// static_cast<int>: memotong bagian desimal
int bulat = static_cast<int>(rataRata);
std::cout << "rataRata = " << rataRata << "\n";
std::cout << "static_cast<int> = " << bulat << "\n\n";
// Mengubah arah pembagian integer menjadi pembagian riil
int total = 7;
int jumlah = 2;
std::cout << "total / jumlah = " << total / jumlah << "\n";
double persen = static_cast<double>(total) / jumlah;
std::cout << "double(total) / 2 = " << persen << "\n\n";
// char ke kode numeriknya
char huruf = 'A';
int kode = static_cast<int>(huruf);
std::cout << "static_cast<int>('A') = " << kode << "\n";
return 0;
}Output yang Dihasilkan:
rataRata = 87.6
static_cast<int> = 87
total / jumlah = 3
double(total) / 2 = 3.5
static_cast<int>('A') = 65Mari kita bedah:
- Baris 7-9 (
static_cast<int>(rataRata)): konversi87.6menjadi87— bagian desimal dipotong, bukan dibulatkan. Tanpa cast, compiler justru memberi peringatan narrowing pada beberapa pola inisialisasi (Chapter Narrowing Conversion). - Baris 13-16: contoh yang sudah kita lihat pada Chapter Operator Aritmetika, kini dengan alat yang benar.
static_cast<double>(total)mengubah7menjadi7.0, sehingga pembagian berjalan riil dan menghasilkan3.5. - Baris 19-21 (
static_cast<int>(huruf)):charsebenarnya menyimpan kode integer;static_cast<int>menampilkannya, dan'A'bernilai65pada skema ASCII.
Catatan penting: cast tidak mengubah variabel asal. rataRata tetap 87.6 setelah baris cast; yang dikonversi adalah nilai hasil bacaannya.
Tiga Cast Lainnya: Pratinjau Singkat #
dynamic_cast: Navigasi Hierarki Class #
dynamic_cast mengubah pointer atau reference antar class yang saling berhubungan melalui inheritance, dengan pemeriksaan tipe saat runtime. Dipakai saat kita memegang pointer ke class dasar tetapi butuh memastikan objeknya sebenarnya class turunan tertentu:
// Akan bermakna setelah Section Pemrograman Berorientasi Objek
Hewan* h = ambilHewanAcak(); // bisa Anjing, bisa Kucing
Anjing* a = dynamic_cast<Anjing*>(h); // nullptr bila h bukan Anjing
Pola menanyakan nullptr setelah cast inilah alasan dynamic_cast aman dibanding menebak tipe. Pembahasan lengkapnya menyambung dengan Chapter Polymorphism karena hanya bekerja pada class polymorphic (yang punya fungsi virtual).
const_cast: Menambah atau Melepas const #
const_cast adalah satu-satunya cast yang boleh menyentuh kualifikasi const:
const int BATAS = 42;
int* p = const_cast<int*>(&BATAS); // sah untuk di-tulis? TIDAK — baca di bawah
reinterpret_cast: Menafsir Ulang Bit #
reinterpret_cast menyuruh compiler: “perlakukan bit-nya sebagai tipe lain, tanpa konversi apa pun”. Ranahnya low-level — pointer ke integer, antarmuka ke hardware, atau interoperabilitas C — dan hasilnya bergantung platform:
long alamat = reinterpret_cast<long>(&nilai); // bit alamat dibaca sebagai long
Cast ini paling jarang dibenarkan: tidak portabel antar arsitektur, dan salah pakai membuat program membaca memori secara salah tanpa kegagalan yang jelas. Bila terpikir memakainya, nyaris selalu ada desain yang lebih bersih.
C-Style Cast dan Mengapa Dihindari #
Kode lama bergaya C menulis cast sebagai (tipe)nilai, misalnya (int)rataRata. Bentuk ini bekerja, tetapi punya satu masalah besar: compiler akan mencoba beragam cara cast sampai satu berhasil — mencampur kemampuan static_cast, const_cast, dan reinterpret_cast dalam satu sintaks. Akibatnya niat penulis tidak terbaca, dan kesalahan berbahaya (misalnya tak sengaja melepas const) lolos tanpa terlihat. Ditambah lagi, pola (int) sulit dicari di kode besar.
Tabel kecil merangkum kapan masing-masing tepat:
| Cast | Dipakai untuk | Risiko |
|---|---|---|
static_cast | konversi bermakna antar tipe terkait | rendah; potensi pemotongan nilai |
dynamic_cast | pointer/reference antar class ber-inheritance | aman; hasil nullptr bila gagal |
const_cast | menambah/melepas const | tulis ke objek asli const = UB |
reinterpret_cast | tafsir ulang bit, low-level | tinggi; tidak portabel |
(tipe)nilai | kode C lama | sulit ditebak niatnya |
Setelah mengenal cara mengubah tipe, Chapter berikutnya membahas operator yang tidak mengubah apa pun tetapi mengukur: sizeof, yang melaporkan berapa byte sebuah tipe atau ekspresi.