author Ahmad Muhardian

Belajar C++ #12: Mengenal Tipe Data Struct


Memahami struct di C++

Halo, selamat datang kembali di tutorial belajar C++.

Pada tutorial ini, kita akan belajar tentang tipe data Struct di C++. Tipe data Struct ini sebenarnya mirip-mirip seperti Enum.

Jika kamu belum belajar Enum, saya sarankan untuk mempelajarinya dulu. Silakan klik link berikut untuk mempelajarinya:

Buat kamu yang sudah..

Mari kita mulai belajar Struct.

Apa itu Struct?

Structure atau struct adalah kumpulan dari beberapa variabel dengan beragam tipe data yang dibungkus dalam satu variabel.

Dalam bahasa pemrograman lain, struct ini bisa disamakan seperti:

Nah, untuk bahasa pemrograman yang masih dekat dengan C seperti C++, Kita nyebutnya Struct.

Mengapa kita membutuhkan struct?

Sekarang coba perhatikan contoh kasus berikut:

Misalnya kita ingin menyimpan data mahasiswa. Kita bisa saja melakukannya seperti ini:

string name = "Dian";
string address = "Mataram";
int age = 22;

Lalu bagaimana kalau ada lebih dari satu mahasiswa?

Mungkin bisa saja kita buat seperti ini:

string name = "Dian";
string address = "Mataram";
int age = 22;

string name2 = "Bambang";
string address2 = "Surabaya";
int age2 = 23;

string name3 = "Bimo";
string address3 = "Jakarta";
int age3 = 23;

Ugh! terlihat kurang bagus.

Biar tidak membuat banyak variabel seperti ini, maka variabel-variabel yang masih dalam satu kelompok bisa kita bungkus di dalam struct.

Gimana caranya?

Mari kita pelajari:

Cara Membuat Struct

Struct dapat kita buat dengan kata kunci struct kemudian diikuti dengan nama struct dan isinya.

Cara membuat struct

Contoh:

struct Mahasiswa
{
    string name;
    string address;
    int age;
};

Pada contoh ini, kita membuat struct dengan nama Mahasiswa yang di dalamnya terdapat tiga variabel, yakni name, address, dan age.

Selain dengan cara di atas, kita juga bisa membuat Struct dengan kata kunci typedef. Kata kunci ini untuk membuat custom tipe data baru di C++.

Contohnya:

typedef struct 
{
  string name;
  string address;
  int age;
} Mahasiswa;

Jika menggunakan typedef, maka nama Struct-nya ditulis di belakang.

Sebenarnya bisa juga di depan seperti ini:

typedef struct Mahasiswa 
{
  string name;
  string address;
  int age;
};

Apa bedanya Struct yang menggunakan typedef dengan yang tidak?

Struct yang menggunakan typedef akan dianggap sebagai tipe data dan kita bisa buat variabel instance tanpa harus menggunakan struct. Btw, ini berlaku untuk bahasa C. Kalau di bahasa C++, tanpa typedef pun bisa.

Oke, sekarang bagaimana cara menggunakan struct ini?

Cara Menggunakan Struct

Agar struct dapat digunakan, kita harus membuat variabel dengan tipe data struct.

Contoh:

Mahasiswa mhs1;

Pada contoh ini, kita membuat variabel mhs1 dengan tipe data Mahasiswa yang mana tipe data Mahasiswa ini adalah nama struct-nya.

Lalu untuk mengisi nilai ke variabel mhs1, kita bisa panggil nama variabel member dari struct-nya.

Contoh:

mhs1.name = "Budi";
mhs1.address = "Jakarta";
mhs1.age = 22;

Atau bisa juga diisi langsung saat membuat variabel, dengan cara seperti ini:

Mahasiswa mhs1 = {
  .name = "Budi",
  .address = "Jakarta",
  .age = 22
};

Cara ini disebut dengan designated initializers.

Btw, cara ini bisa dilakukan di versi C++20 ya. Kalau kamu pakai C++ di bawah C++20 cara ini nggak akan bisa dilakukan.

Cara lain, bisa juga seperti ini:

Mahasiswa mhs1 = {"Budi", "Jakarta", 22};

Nah, kalau cara yang ini disebut Aggregate initialization 1. Mulai ada pada versi C++11.

Lalu, cara mana yang harus kita pakai?

Bebas sih mau pakai cara mana aja, yang terpenting sesuaikan dengan versi C++ yang kamu gunakan.

Sekarang mari kita coba latihan!

Latihan: Menggunakan Struct di C++

Buatlah program baru dengan nama latihan_struct.c kemudian isi dengan kode berikut.

#include <iostream>
using namespace std;

// membuat struct
struct Mahasiswa {
    string name;
    string address;
    int age;
};

int main(){

    // menggunakan struct
    Mahasiswa mhs1;

    // mengisi nilai ke struct
    mhs1.name = "Dian";
    mhs1.address = "Mataram";
    mhs1.age = 22;

    Mahasiswa mhs2 = {"Bambang", "Surabaya", 23};

    // mencetak isi struct
    cout << "## Mahasiswa 1 ##\n";
    cout << "Nama: " << mhs1.name << endl;
    cout << "Alamat: " << mhs1.address << endl;
    cout << "Umur: " << mhs1.age << endl;

    cout << "## Mahasiswa 2 ##\n";
    cout << "Nama: " << mhs2.name << endl;
    cout << "Alamat: " << mhs2.address << endl;
    cout << "Umur: " << mhs2.age << endl;

    return 0;
}

Hasilnya:

Menggunakan Struct dalam program C

Struct di dalam Struct (Nested Struct)

Struct bisa juga kita buat di dalam struct. Ini disebut dengan Nested Struct atau struct bersarang.

Contoh:

struct Weapon 
{
    string name;
    int attackPower;
    int range;
};

struct Player
{
    string name;
    int healthPoin;
    Weapon weapon;
};

Lalu cara menggunakannya akan seperti ini:

Player player1;

player1.name = "Petani Kode";
player1.healthPoin = 100;
player1.weapon.name = "Katana";
player1.weapon.attackPower = 30;
player1.weapon.range = 100;

Atau bisa juga seperti ini:

Player player1 = {
    .name = "Petani Kode",
    .healthPoin = 100, // 100%
    .weapon = {
        .name = "Katana",
        .attackPower = 30,
        .range = 100, // 1 meter
    }
};

Atau bisa juga seperti ini:

Player player1 = { "Petani Kode", 100, {"Katana", 30, 100}};

Passing Struct ke dalam Fungsi

Struct dapat kita buat sebagai parameter untuk fungsi.

Contoh:

#include <iostream>
using namespace std;

struct Student
{
    string name;
    int age;
};

int main() {
    Student s1;

    cout << "Enter name: ";
    cin >> s1.name;

    cout << "Enter age: ";
    cin >> s1.age;

    display(s1);   // passing structure as an argument

    return 0;
}

// membuat fungsi dengan struct sebagai parameter
void display(Student s) {
  cout << "Displaying information\n";
  cout << "Name: " << s.name << endl;
  cout << "Age:" << s.age << endl; 
}

Hasilnya:

Struct sebagai parameter pada fungsi

Menyimpan Fungsi di dalam Struct

Selain menyimpan variabel, ternyata kita juga bisa menyimpan fungsi dalam Struct.

Contohnya:

struct Player {
  string name;
  int healthPoin;
  void showPlayerStatus(){
    cout << "Name: " << name << endl;
    cout << "HP: " << healthPoin << endl;
  }
};

Lalu cara memanggilnya akan seperti ini:

// membuat variabel untuk struct
Player p1;

// memanggil fungsi yang ada di dalam struct
p1.showPlayerStatus();

Biar lebih paham, mari kita coba latihan:

Buatlah file baru dengan nama struct_fungsi.cpp, kemudian isi dengan kode berikut:

#include <iostream>
using namespace std;

// mendefinisikan struct Player
struct Player {
  string name;
  int healthPoin;

  // kita tambahkan fungsi di dalam struct ini
  void showPlayerStatus() {
    cout << "-- Player Status --\n";
    cout << "Nama: " << name << endl;
    cout << "HP: " << healthPoin << endl;
  }
};

int main() {
  // membuat dan mengisi nilai ke struct
  Player p1 = {
    .name = "Petani Kode", 
    .healthPoin = 100
  };

  // memanggil fungsi yang ada di dalam struct
  p1.showPlayerStatus();

  return 0;
}

Pada contoh ini, kita membuat struct Player dan di dalamnya terdapat fungsi showPlayerStatus(). Fungsi ini akan mencetak status dari Player.

Mari kita coba compile dan jalankan.

Maka hasilnya:

Contoh fungsi di dalam struct

Jika Struct bisa diisi dengan fungsi, lalu apa bedanya dengan class?

Struct sebenarnya hampir sama seperti class. Kalau dalam OOP (Object Oriented Programming), kita harus buat prototipe object dulu dengan class. Tapi sebenarnya bisa juga dilakukan dengan Struct.

Nah, bedanya Struct dengan class terletak pada hak akses membernya. Kalau Struct secara default bisa diakses secara publik. Sementara class, membernya bisa kita set public, private, dan protected.

Oh iya, buat kamu yang belum paham konsep OOP. Mungkin kamu akan bingung di bagian ini. Tapi tidak masalah, nanti kalau sudah paham OOP, coba pelajari lagi ini pasti langsung paham.

Mari kita lanjut bahas:

Fungsi Constructor dan Destructor di Struct

Fungsi Constructor adalah fungsi yang akan dipanggil saat pembuatan object atau variabel dari struct. Sedangkan Destructor akan dipanggil saat variabel atau object tersebut dihapus.

Cara menambahkan fungsi constructor dan destructor di Struct sama seperti menambahkan fungsi biasa. Tapi tanpa return type dan nama fungsinya harus sama dengan nama Struct. Untuk fungsi destructor, namanya harus ditambahkan ~ di depan.

Contoh:

struct Player {
  string name;
  int hp;

  // fungsi constructor
  Player(){ ... }

  // fungsi destructor
  ~Player() { ... } 
}

Perhatikan..

Pada contoh ini, ada dua fungsi yang kita tambahkan pada struct Player, yakni fungsi Player() dan ~Player().

Fungsi Player() adalah constructor dan ~Player() adalah destructor. Di dalam kedua fungsi ini bisa kita isi perintah-perintah untuk dikerjakan.

Misalnya seperti ini:

struct Player {
  string name;
  int hp;

  Player(){ 
    cout << "Object Player dibuat" << endl; 
  }
  
  ~Player() { 
    cout << "Object Player dihancurkan" << endl; 
  } 
}

Pada contoh ini, kita menampilkan teks dengan cout di fungsi constructor Player() dan destructor ~Player(). Nantinya, saat struct ini dibuat maka fungsi Player() akan dipanggil dan ketika variabelnya dihapus, fungsi ~Player() yang akan dipanggil.

Biar lebih paham, mari kita coba latihan:

Buatlah program baru dengan nama struct_construct_destruct.cpp kemudian isi dengan kode berikut:

#include <iostream>
using namespace std;

struct Player {
  string name;
  int healthPoin;

  Player() { cout << "✨ Object dibuat!" << endl; }
  ~Player() { cout << "🔥 Object dihancurkan!" << endl; }

  void showPlayerStatus() {
    cout << "-- Player Status --\n";
    cout << "Nama: " << name << endl;
    cout << "HP: " << healthPoin << endl;
  }
};

int main() {

  Player p1;
  p1.name = "Petani Kode";
  p1.healthPoin = 100;

  p1.showPlayerStatus();

  return 0;
}

Setelah itu, compile dan jalankan.

Maka hasilnya:

Latihan constructor dan destructor untuk struct

Coba perhatikan!

Pada fungsi main(), kita tidak pernah memanggil fungsi Player() dan juga ~Player(). Tapi mengapa fungsi ini dijalankan?

Ya jelas, karena dia adalah constructor dan destructor. Fungsi Player() akan otomatis dipanggil saat kita membuat variabel p1.

Player p1;

Kemudian fungsi ~Player() akan otomatis dipanggil saat variabel p1 di hapus dari memori. Pada program di atas, variabel p1 akan otomatis dihapus setelah fungsi main() selesai dijalankan.

Saya harap kamu bisa memahami penjelasan ini.

Apa Selanjutnya?

Sejauh ini kita sudah mengenal dan menggunakan Struct.

Intinya:

Struct itu buat menyimpan beberapa data yang masih berkaitan dalam satu variabel. Selain itu, struct juga bisa menyimpan fungsi layaknya class.

Selanjutnya:

Silakan pelajari tentang tipe data union.

Kalau ada yang kurang dimengerti, silakan tanyakan di komentar.

Selamat belajar!