Pbo C++
Pbo C++
SEKOLAH TINGGI MANAJEMEN INFORMATIKA DAN ILMU KOMPUTER EL RAHMA YOGYAKARTA 2008
Istilah OOP ( Object Oriented Program ) sudah cukup terkenal karena sejak tahun 1988 telah ada. Dasar pada bahasa berorientasi obyek adalah mengkombinasikan data dan fungsi untuk mengakses data menjadi sebuah kesatuan unit. Unit ini dikenal dengan nama obyek. OOP meliputi beberapa elemen yaitu : - Encapsulation Encapulation berarti menggabungkan struktur data dengan fungsi (tindakan atau metode) yang dipakai untuk memanipulasi data. Gabungan data dan fungsi untuk memanipulasi data itu disebt juga Class ( kelas ). - Inherientence Konsep Inherientence mungkin berasal dari ilmu Biologi. Inherientence adalah mekanisme penciptaan kelas baru yang mewarisi sifat atau karateristik kelas lain yang lebih sederhana. Jika kelas B mewarisi karakteristik kelas A, kita mengatakan bahwa B adalah kelas turunan ( derived class ) dan A adalah kelas dasar (base class ). Jadi dengan inherientence anda dapat melakukan taksonomi. Taksonomi dilakukan untuk membangun hirarki kelas berdasarkan sifat yang diturunkan. - Polymorphism Polymorphism menunjuk pada fakta bahwa satu kegiatan bisa memiliki perilaku yang berbeda diobject yang berbeda. Polymorphism membantu dalam menyederhanakan syntaksis ( kata-kata ) untuk menjalankan kegiatan yang sama pada sekumpulan object atau hirarki kelas. Analogi Struktur dan Kelas Kelas merupakan struktur data dari obyek. Untuk menjelaskan tentang kelas perhatikan contoh program berikut ini : Contoh program : //*---------------------------------------------------------------* //* Contoh 1.1 : Sebuah struktur yang akan digunakan * //* sebagai perbandingan dengan kelas * //*---------------------------------------------------------------* #include <iostream.h> #include <conio.h> #include <string.h> struct buku { char judul[35]; char pengarang[25]; int jumlah; }; void main() { clrscr(); buku novel; // Pendefinisian variabel strcpy(novel.judul, Meriam Benteng Navarone); strcpy(novel.pengarang, Alistair MacLean); novel.jumlah = 12; cout << novel.judul << endl; cout << novel.pengarang << endl; cout << novel.jumlah << endl; } Hasil eksekusi :
Apabila program ini dijalankan, hasil eksekusi akan sama dengan contoh program 1.1. Kata kunci public pada kelas buku didepan biasa disebut sebagai penentu akses (access specifer). Selain public juga terdapat penentu akses berupa private dan protected. Penentu akses private biasa digunakan pada kelas untuk memproteksi anggota-anggota tertentu, agar tidak dapat diakses diluar kelas secara langsung. Konsep obyek pada C++ sebenarnya digunakan untuk menyatukan data dan fungsi yang mengakses data dalam suatu wadah. Misalnya bila terdapat data judul buku, nama pengarang, jumlah buku diawal perancangan harus dipikirkan fungsifungsi dasar yang digunakan untuk mengakses ketiga data tersebut. Fungsi-fungsi tersebut berupa mengisikan data dan menampilkan data. Kemudian juga perlu direncanakan, data atau fungsi mana yang boleh diakses diluar obyek dan hanya dipergunakan secara internal oleh obyek itu sendiri. Dalam hal ini penentu akses public atau private yang menentukannya. Untuk lebih jelasnya perhatikan contoh program berikut : Contoh program : //*--------------------------------------------------------* //* Contoh 1.3 : Sebuah kelas yang melibatkan * //* anggota data dan fungsi anggota * //*--------------------------------------------------------* #include <iostream.h> #include <conio.h> #include <string.h> class buku { private : char judul[35]; char pengarang[25]; int jumlah; public : void inisialisasi ( char *judul, char *pengarang, int jumlah) { strcpy(judul, Judul ); strcpy(pengarang, Pengarang ); jumlah = Jumlah ; } void info () { cout << Judul : << judul << endl; cout << Pengarang : << pengarang << endl; cout << Jumlah Buku : << jumlah << endl; } }; void main() { clrscr(); buku novel; // Pendefinisian obyek novel.inisialisasi ( Meriam Benteng Navarone, Alistair MacLean,12 ); novel.info (); } Judul : Meriam Benteng Navarone Hasil eksekusi :
Pada program diatas, kelas buku memiliki tiga buah anggota data (judul, pengarang dan jumlah) dan dua buah fungsi anggota ( inisialisasi() dan info() ). Ketiga data anggota dinyatakan sebagai prifat. Oleh karena itu, ketiga data ini tidak dapat diakses diluar kelas. Namun data ini dapat diakses oleh kedua fungsi anggota dan semua fungsi anggota dapat diakses diluar kelas, mengingat dinyatakan sebagai publik. Melalui kedua fungsi inlah data kelas dapat diakses. Perlu diketahui, jika terdapat lebih dari satu obyek dan obyek-obyek tersebut mempunyai kelas yang sama, data anggota pada masing-masing obyek bersifat terpisah. Contoh program :
//*----------------------------------------------------------------------------------* //* Contoh 1.4 : Memperlihatkan ketidakkertergantungan anggota data * //* pada dua buah obyek yang mempunyai kelas sama * //*----------------------------------------------------------------------------------* #include <iostream.h> #include <conio.h>
C++ memungkinkan penyalinan nilai antarobyek dapat dilakukan dengan mudah, yaitu cukup menggunakan operator sama dengan ( = ). Perhatikan contoh program berikut : //*----------------------------------------------------------------------* //* Contoh 1.5 : Menunjukan operasi penugasan antar obyek * //*----------------------------------------------------------------------* #include <iostream.h> #include <conio.h> #include <string.h> class buku { privete : char judul[35]; char pengarang[25]; int jumlah; public : void inisialisasi ( char *judul, char *pengarang, int jumlah) { strcpy(judul, Judul ); strcpy(pengarang, Pengarang ); jumlah = Jumlah ; } void info () { cout << Judul : << judul << endl; cout << Pengarang : << pengarang << endl; cout << Jumlah Buku : << jumlah << endl; } };
nama_kelas::nama_anggota_data
Contoh program : //*---------------------------------------------------------------* //* Contoh 1.7 : Penulisan anggota pada fungsi anggota * //* dengan format kelas::data * //*----------------------------------------------------------------* #include <iostream.h> #include <conio.h> #include <string.h> class buku { privete : char judul[35]; char pengarang[25]; int jumlah; public : void inisialisasi ( char *judul, char *pengarang, int *jumlah) void info (); }; void main() { clrscr(); buku novel; // Pendefinisian obyek novel.inisialisasi ( Meriam Benteng Navarone, Alistair MacLean,12 ); novel.info(); } void buku::inisialisasi ( char *judul, char *pengarang, int *jumlah) { strcpy(buku::judul, judul ); strcpy(buku::pengarang, pengarang ); buku::jumlah = jumlah ; } void buku::info () { cout << Judul : << judul << endl; cout << Pengarang : << pengarang << endl; cout << Jumlah Buku : << jumlah << endl; } Seperti halnya fungsi biasa, fungsi anggota juga bisa mempunyai nilai balik. Perhatikan contoh berikut ini : //*--------------------------------------------------------------------------* //* Contoh 1.8 : Program yang memeperlihatkan fungsi anggota * //* yang memepunyai nilai balik * //*--------------------------------------------------------------------------* #include <iostream.h> #include <conio.h> #include <iomanip.h> class Tanggal { private : int tanggal; int bulan; int tahun; public : void beri_tanggal(int tanggal, int bulan, int tahun); void info(); int info_tanggal() {return tanggal };
Pada kelas Tanggal diatas terdapat lima fungsi anggota. Tiga diantaranya mempunyai nilai balik bertipe int. Ketiga fungsi anggota ini didefinisikan secara inline, sedangkan dua lainnya disefinisikan diluar kelas.
Tanggal 28-11-1982
: 28/11/1982
Tugas Praktikum : Pada Contoh Program 1.8 anda dapat melihat hasil eksekusi berupa penampilan tanggal Buatlah program seperti contoh program 1.8 dimana data diinputkan dari keyboard. Contoh : Masukkan Tanggal : 28 Masukkan Bulan : 11 Masukkan Tahun : 1982 Hasil Output : 28/11/1982 28 November 1982 (simpan dengan nama tuoop1.cpp)
MODUL II KONTRUKTOR DAN DESTRUKTOR 2.1. Konstruktor Konstruktor adalah fungsi anggota yang mempunyai nama yang sama dengan nama kelas. Kegunaannya yaitu : 1. Mengalokasikan ruang bagi sebuah obyek 2. memberikan nilai awal terhadap anggota data suatu obyek 3. membentuk tugas-tugas umum lainnya Untuk melihat efek konstruktor, perhatikan contoh program berikut : //*---------------------------------------------------------* //* Contoh 2.1 : Memperlihatkan efek konstruktor * //*---------------------------------------------------------* #include <iostream.h> #include <conio.h> class Kompleks { private : double re; // Nilai real double im; // Nilai imajiner public : Kompleks(); // Konstruktor void info(); }; void main () { clrscr() ; Kompleks a; // Mendefinisikan obyek a
} // Definisi fungsi anggota kelas Kompleks Kompleks::Kompleks() { cout << Konstruktor dijalankan........ << endl; re = 5.2; im = 3.6; } void Kompleks::info() { cout << \nBilangan kompleks : << endl; cout << real = << re << endl; cout << imajiner = << im << endl; cout << endl; } Hasil eksekusi :
Konstruktor dijalankan. Bilangan kompleks : real = 5.2 imajiner = 3.6 Konstruktor dijalankan.
Hasil didepan menunjukan bahwa konstruktor dijalankan dengan sendirinya saat obyek a dan b diciptakan melalui pernyataan : real = 5.2 Kompleks a; imajiner Kompleks b; = 3.6 Suatu konstruktor dapat juga memiliki sebuah argumen. Argumen ini bermanfaat untuk memberi nilai awal terhadap anggota data pada saat obyek diciptakan. Perhatikan contoh program berikut : //*----------------------------------------------------* //* Contoh 2.2 : Konstruktor dengan argumen * //*----------------------------------------------------* #include <iostream.h> #include <conio.h> #include <string.h> class Buku { private : char judul[35]; char pengarang[25]; int jumlah; public : Buku(char *judul, char *pengarang, int jumlah); void info(); }; void main() { clrscr(); Buku novel(Siaga Merah, Alistair MacLean, 3); novel.info(); } // Definisi fungsi anggota Buku::Buku(char *judul, char *pengarang, int jumlah) { strcpy(Buku::judul, judul); strcpy(Buku::pengarang, pengarang); Buku::jumlah = jumlah } void Buku::info() { cout << Judul : << judul << endl; cout << Pengarang : << pengarang << endl; cout << Jumlah : << jumlah << endl; } Hasil eksekusi :
Tampka bahwa konstruktor Buku mempunyai tiga buah argumen. Dengan adanya pendeklarasian seperti diatas maka obyak dapat disefinisikan dengan cara : Buku novel(Siaga Merah, Alistair MacLean, 3); Pernyataan diatas sekaligus memberi nilai awal terhadap anggota data. Selain dapat dibuat sebagai argumen, nilai bawaan dapat diterapkan dalam konstruktor. Perhatikan contoh program berikut : //*--------------------------------------------------------------------* //* Contoh 2.3 : Konstruktor dengan argumen mengandung * //* nilai bawaan (default) * //*--------------------------------------------------------------------* #include <iostream.h> #include <conio.h> #include <string.h> class Buku { private : char judul[35]; char pengarang[25]; int jumlah; public : Buku(char *judul = Judul KOSONG, char *pengarang = Pengarang KOSONG, int jumlah = 0); void info(); }; void main() { clrscr(); Buku novel1; Buku novel2(Partisan); Buku novel3(Matahari Terbit, Michael Crichton); Buku novel4(Siaga Merah, Alistair MacLean, 3); novel1.info(); novel2.info(); novel3.info(); novel4.info(); } // Definisi fungsi anggota Buku::Buku(char *judul, char *pengarang, int jumlah) { strcpy(Buku::judul, judul); strcpy(Buku::pengarang, pengarang); Buku::jumlah = jumlah } void Buku::info() { cout << Judul : << judul << endl; cout << Pengarang : << pengarang << endl; cout << Jumlah : << jumlah << endl; } Hasil eksekusi :
: Judul KOSONG : Pengarang KOSONG :0 : Partisan : Pengarang KOSONG :0 : Matahari Terbit : Michael Crichton :0
Nilai bawaan untuk argumen judul adalah Judul KOSONG dan pengarang adalah Pengarang KOSONG dan jumlah sama dengan nol. Dengan menambahkan nilai bawaan seperti ini, pemberian nilai awal dapat dilakukan dengan berbagai bentuk. Judul : Siaga Merah Destruktor Pengarang : Alistair MacLean Destruktor adalah fungsi anggota kelas yang akan dijalankan secara otomatis pada obyek yang akan sirna. Nama Jumlah dengan :nama konstruktor, hanya saja diawali dengan sebuah karakter tak-berhingga (~). Perhatikan contoh 3 destruktor sama program berikut : //*-----------------------------------------------------*
10
//*---------------------------------------------------------------------* //* Contoh 2.5 : Pengalokasian dinamis dan pen-dealokasian* //* memori melalui operator new dan delete * //*---------------------------------------------------------------------* #include <iostream.h> #include <conio.h> #include <string.h> class Mobil { private : char *nama; int cc_mesin; int jumlah_pintu; public : Mobil(char *nama_mobil, int cc, int jum_pintu); ~Mobil(); // Destruktor void keterangan(); }; void main() {
11
Infomasi mobil : Nama : charade classy CC mesin : 1300 Jumalah pintu : 5 Informasi mobil : Nama : datsun Pada contoh mesin diatas, anggota data nama merupakan pointer yang menunjuk ke tipe char. Lokasi yang ditunjukkan CC program : 1000 dialokasikan di heap. Oleh 2 Jumlah pintu : karena obyek yang diciptkan akan menggunakan lokasi di heap, obyek juga harus membenaskan
Tugas Praktikum : Buatlah program untuk memasukkan tanggal lahir anda dan teman kelompok anda, gunakan kontruktor dan destruktor. (simpan dengan nama tuopp2.cpp)
12
Jika sutu kelas dimasudkan untuk digunakan pada sejumlah program, akan lebih baik kalau kelas dideklarasikan pada file tersendiri dan begitu juga untuk definisi fungsi-fungsi anggotanya. Untuk lebih jelasnya perhatikan file bernama buku.h dan buku.cpp berikut : //*-------------------------------------------* //* Contoh 3.1 : Deklarasi kelas buku * //*-------------------------------------------* #ifndef_buku #define_buku class buku { private : char judul[35]; char pengarang[25]; int jumlah; public : Buku(char *judul = Judul KOSONG, char *pengarang = Pengarang KOSONG, int jumlah = 0; void info(); }; #endif pada contoh program diatas, baris : - #ifndef_buku : berfungsi untuk memeriksa ada tidaknya pengenal dengan nama buku. Kalau tidak ada, maka bagian yang terletak antara #ifndef _buku hingga #endif akan diproses (pada saat kompilasi). - #define _buku : berfungsi untuk mendefinisikan pengenal _buku dan pendefinisian ini hanya akan dilakukan kalau sebelumnya terdapat pengenal _buku. Perhatikan contoh program berikut : //*------------------------------------------------------------------* //* Contoh 3.2 : File berisi definisi fungsi-fungsi anggota * //* kelas buku * //*------------------------------------------------------------------* #include <iostream.h> #include <conio.h> #include buku.h Buku::Buku(char *judul, char *pengarang, int jumlah) { strcpy(Buku::judul, judul); strcpy(Buku::pengarang, pengarang); Buku::jumlah = jumlah; } void Buku::info() { cout << Judul : << judul << endl; cout << Pengarang : << pengarang << endl; cout << Jumlah buku : << jumlah << \n << endl; } Pada Borland C++ program diatas dapat dikompilasi dengan menggunakan perintah bcc c buku lalu lanjutkan dengan program berikut : //*----------------------------------------------------------------------------* //* Contoh 3.3 : Program menggunakan kelas yang dideklarasikan* //* pada file header buku.h * //*----------------------------------------------------------------------------* #include <iostream.h> #include <conio.h> #include buku.h // Menyertakan file buku.h void main() { clrscr(0; Buku literatur; Buku novel(The Eagle Has Flown, Jack Higgis, 1); literatur.info(); novel.info(); } Hasil eksekusi :
Judul : Judul KOSONG Pengarang : Pengarang KOSONG Jumlah buku : 0 Judul : The Eagle Has Flown Pengarang : Jack Higgis Jumlah buku : 1
13
Apabila bermaksud mendefinisikan suatu pointer yang menunjuk ke suatu obyek kita dapat memeberikan pernyataan sebagai berikut : Buku *nonfiksi Seperti biasa, tanda * diberikan didepan nama variabel pointer. Perhatikan contoh program berikut : //*----------------------------------------------------------* //* Contoh 3.4 : Pointer yang menunjuk ke Obyek * //*----------------------------------------------------------* #include <iostrream.h> #include <conio.h> #include buku.h void main() { clrscr(); Buku *nonfiksi; nonfiksi = new Buku (Pemrograman C++, Abdul kadir, 4); nonfiksi -> info(); } Hasil eksekusi :
14
obyek buah1 Jumlah apel = 20 obyek buah2 Jumlah apel = 12 obyek buah3 Jumlah apel = 32
Jeruk = 5
Jeruk = 4
Jeruk = 9
15
Pada contoh program diatas pernyataan buah3 = buah1.tambah(buah2); , anggota data buah3 berisi penjumlahan dari anggota data buah1 dan buah2. Pernyataan lain seperti Buah tmp; , mendefinisikan obyek lokal bernama tmp. Dan terdapat penyataan tmp.apel = apel + b2.apel; , apel menyatakan anggota data dari obyek sekarang, tmp.apel menyatakan anggota data dari obyek tmp, b2.apel menyatakan anggota data dari obyek b2. hal serupa juga berlaku untuk anggota data jeruk. Kemudian return(tmp) akan memberikan nilai balik berupa salinan dari obyek tmp. Suatu pointer yang menunjuk ke fungsi anggota dapat dibentuk oleh pemrogram. Dengan cara seperti ini, fungsi anggota suatu obyek dapat diakses melalui pointer. Kaidah untuk menciptakan pointer seperti berikut :
Tipe (NamaKelas::*NamaPointer)(Parameter,)
Perhatikan contoh program berikut : //*-------------------------------------------------------------------* //* Contoh 3.8 : Pointer yang menunjuk ke fungsi anggota * //*-------------------------------------------------------------------* #include <iostream.h> #include <conio.h> class KelasX { public : void fung_1() { cout << fung_1() dijalankan ... << endl; } void fung_2() { cout << fung_2() dijalankan ... << endl; } int fung_3(int a, int b) { return (a + b); } }; void main() { clrscr(); void (KelasX::*ptr_fungsi) (void); // Ptr ke fungsi KelasX x; // Obyek x cout << Via fungsi anggota << endl; x.fung_1(); x.fung_2(); cout << 5 + 8 = << x.fung3(5, 8) << endl; ptr_fungsi = &KelasX::fung_1; (x.*ptr_fungsi) (); ptr_fungsi = &KelasX::fung_2; (x.*ptr_fungsi) (); int (KelasX::*ptr_fungsi2) (int, int); // Ptr ke fungsi ptr_fungsi2 = &KelasX::fung_3; cout << 5 + 8 = << x.*ptr_fungsi2) (5, 8) << endl; } Hasil eksekusi :
Via fungsi anggota fung_1() dijalankan fung_2() dijalankan 5 + 8 = 13 Via pointer ke fungsi anggota fung_1() dijalankan fung_2() dijalankan Pada program diatas terlihat bahwa dengan menggunakan pointer yang menunjuk ke fungsi anggota, pointer dapat diatur untuk menunjuk13 fung_1() dan fung2() secara bergantian. 5 + 8 = ke
Tugas Praktikum Buatlah sebuah program untuk menjumlahkan tanggal lahir anda dengan teman anda menggunakan aturan pointer ke fungsi anggota. (simpan dengan nama tuoop3.cpp ).
16
17
Operator pada C++ yang dapat di-overloading sangat banyak. Tabel berikut menyatakan operator-operator yang tidak dapat di-overloading. Operator Kegunaan Contoh Operator anggota struktur atau kelas cin.getline() . Operator pointer ke anggota obyek.*anggota .* Operator resolusi lingkup nama_kelas::anggota :: Operator ungkapan kondisi c = (a > b) ? a : b ?: Operator untuk memperoleh ukuran data sizeof(int) Sizeof Untuk memahami gambaran tentang overloading terhadap operator biner (operator dengan dua operand), perhatikan program berikut : //*------------------------------------------------------------------------* //* contoh 4.1 : Menunjukan overloading terhadap operator + * //*------------------------------------------------------------------------* #include <iostream.h> #include <conio.h> class Buah { private : int apel; int jeruk; public : Buah(int jum_apel = 0, int jum_jeruk = 0); void info_buah(); Buah operator + (Buah b2); }; void main() { clrscr(); Buah buah1 (20, 5); Buah buah2 (12, 4); Buah buah3; buah3 = buah1 + buah2 ; cout << obyek buah1 << endl; buah1.info_buah(); cout << obyek buah2 << endl; buah2.info_buah(); cout << obyek buah3 << endl; buah3.info_buah(); } // Definisi fungsi anggota Buah::Buah(int jum_apel, int jum_jeruk) { apel = jum_apel; jeruk = jum_jeruk; } void Buah::info_buah() { cout << Jumlah apel = << apel << Jeruk = << jeruk << \n << endl; } Buah Buah::operator + (Buah b2) { Buah tmp; // Obyek sementara tmp.apel = apel + b2.apel; tmp.jeruk = jeruk + b2.jeruk; obyek buah1 return(tmp); Jumlah apel = 20 Jeruk = 5 } Hasil eksekusi :
Jeruk = 4
Contoh program diatas menyerupai contoh program 3.7 pada Bab III. Perbedaan utamanya, kata tambah diganti dengan Jumlah apel = 32 Jeruk = 9 operator +. Dalam bentuk yang umum, overloading terhadap oparator biner berupa :
18
Jeruk = 5
Jeruk = 10
Contoh berikut menunjukkan bentuk overloading terhadap operator unary, yaitu operator yang mempunyai sebuah operand. //*---------------------------------------------------------------------* //* Contoh 4.3 : menunjukan overloading terhadap operator * //* ++ dan -* //*---------------------------------------------------------------------* #include <iostream.h> #include <conio.h> class Buah { private : int apel; int jeruk;
Jeruk = 10
19
Jeruk = 5
Setelah dinaikkan 2x : Jumlah apel = 22 Jeruk = 7 Setelah diturunkan 1x : Jumlah apel = 21 Jeruk = 6
Dari contoh program diatas terlihat bahwa overloading terhadap operator unary lebih sederhana dibanding dengan operator biner. Perlu diketahui, bentuk definisi operator ++ dan pada program 4.3 tidak bisa menangani operasi seperti berikut : Buah paket2; paket2 = ++paket1; karena fungsi operator ++ dinyatakan tidak mempunyai nilai balik (void). Agar dapat dilaksanakan, fungsi operator ++ harus didefinisikan mempunyai nilai balik berupa Buah. Lebih jelasnya, fungsi operator ++ perlu didefinisikan sebagai berikut : Buah Buah::operator ++ () { Buah tmp; tmp.apel = ++apel; tmp.jeruk = ++jeruk; return(tmp) } Dalam hal ini diperlukan obyek sementara (tmp). Kemudian anggota data obyek ini diisi dengan anggota data obyek sekarang dan selanjutnya tmp dijadikan nilai balik. Overloading juga dapat dilakukan terhadap operator relasi dan logika (seperti >,==,!= ataupun &&). Program berikut memberikan gambaran cara untuk melakukannya : //*------------------------------------------------------------------------* //* Contoh 4.4 : Untuk menggambarkan overloading terhadap * //* operator > *
20
barang1 lebih murah dari barang2 barang2 tidak lebih murah dari barang3
Prinsip utama dalam melakukan overloading terhadap operator logika dan relasi adalah mengatur nilai balik fungsi operator agar berupa nilai benar (1) atau salah (0). Operator majemuk (seprti +=, /= dan *=) juga dapat di overloading. Perhatikan contoh progam berikut : //*----------------------------------------------------------------------------------* //* Contoh 4.5 : untuk menunjukan overloading terhadap operator += * //*----------------------------------------------------------------------------------* #include <iostream.h> #include <conio.h> class Buah { private : int apel; int jeruk; public : Buah(int = 0, int = 0); void info_buah(); Buah operator +=(Buah); }; void main() { clrscr(); Buah buah2 (20, 5); Buah buah1 (12, 4); cout << obyek buah1 << endl;
21
Jeruk = 5
Jeruk = 4
MODUL V INHERITANCE (PEWARISAN) Suatu kelas yamg mewarisi data ataupun fungsi anggota kelas lain disebut Pewarisan. Kelas yang mewarisi sifat kelas lain disebut kelas turunan (derived class) dan kelas yang mewariskan sifat kekelas lain bisas dinamakan kelas dasar(base class). Keuntungan utama adanya pewarisan yaitu memungkinkan suatu kode-kode yang telah ditulis mudah sekali untuk digunakan kembali. Untuk memahami konsep pewarisan, perhatikan contoh program berikut : //*--------------------------------------* //* Contoh 5.1 : Pewarisan kelas * //*--------------------------------------* #include <iostream.h> #include < conio.h> class Basis { private : int alpha; // untuk sementara tidak dipakai int bravo; public : void info_basis() { cout << info_basis() dijalankan... << endl; } }; class Turunan : public Basis
22
Alpha = 2
bravo = 5
Dengan menjadikan anggota alpha dan bravo sebagi protected, kedua anggota ini dapat diakses pada kelas Turunan, tetapi tidak dapat diakses pada fungsi main(). Dalam pewarisan juga dikenal dengan pewarisan bertingkat. Perhatikan program berikut ini : //*------------------------------------------------------------* //* Contoh 5.3 : Pewarisan dengan beberapa tingkat * //*------------------------------------------------------------* #include <iostream.h> #include <conio.h> #include <string.h> class Orang { private : char nama[50];
23
24
Hal terpenting dalam membuat pewarisan bertingkat adalah menginisialisasi konstruktor kelas dasarnya dari konstruktor kelas turunan. Selain pewarisan bertingkat adapula pewarisan berganda maksudnya diperkenankan sebuah kelas mewarisi lebih dari satu kelas, perhatikan contoh program berikut ini : //*------------------------------------------* //* Contoh 5.4 : Pewarisan berganda * //*------------------------------------------* #include <iostream.h> #include <conio.h> #include <string.h> class Buku { private : char judul[35]; char pengarang[25]; long harga; public : Buku(char *judul, char *pengarang, long harga); void info_buku(); }; class Disket { private : char ukuran[15]; long harga; public : Disket(char *ukuran, long harga); void info_disket(); }; class PaketBukuDisket : public Buku, public Disket { private : long harga; public : PaketBukuDisket(char *judul, char *pengarang, long harga_buku, char *ukuran, long harga_disk); void info_paket(); }; void main() { PaketBukuDisket cpp(C++, Alakadabra, 25000, 3 inci, 12000) cpp.info_paket(); } Buku::Buku(char *judul, char *pengarang, long harga); { strcpy(Buku::judul, judul); strcpy(Buku::pengarang, pengarang); Buku::harga = harga; } void Buku::info_buku() { cout << Judul Buku : << judul << endl; cout << Pengarang : << pengarang << endl; cout << Harga Buku : << harga << endl; } Disket::Disket(char *ukuran, long harga) { strcpy(Disket::ukuran, ukuran); Buku::harga = harga; } void Disket::info_disket() { cout << Ukuran disket : << ukuran << endl; cout << Harga disket : << harga << endl; } PaketBukuDisket::PaketBukuDisket( char *judul, char *pengarang, long harga_buku, char *ukuran, long harga_disket); Buku(judul, pengarang, harga_buku); Disket(ukuran, harga_disket) { harga = harga_buku + harga_disket; }
25
Judul buku Pengarang Harga buku Ukuran disket Harga disket Harga total Tugas Praktikum :
Buatlah program untuk menghitung total nilai 3 mata praktikum dengan menggunakan pewarisan berganda. (simpan dengan nama tugoop5.cpp)
MODUL VI POLIMORFISME Polimorfisme, sesuai dengan asal-usul kata pembentuknya adalah mempunyai banyak bentuk. Polimorfisme mempunyai untuk menengani dua atau lebih bentuk obyek yang berlainan pada saat eksekusi berlangsung. Yang menjadi dasar polimorfisme adalah fungsi virtual. Suatu fungsi anggota dapat dijadikan sebagai funsi virtual jika fungsi dideklarasikan kembali pada kelas turunan dan suatu pointer menunjuk kelas dasar yang diciptakan. Pointer dapat memilih obyek yang tepat sekiranya fungsi anggota tersebut dipanggil via pointer. Untuk memudahkan memahami funsi firtual, perhatikan contoh dibawah ini : //*----------------------------------------------------* //* Contoh 6.1 : Untuk memeperlihatkan efek * //* fungsi virtual * //*----------------------------------------------------* #include <iostream.h> #include <conio.h> class Makhluk { public : void informasi() { cout << informasi() pada Makhluk... << endl; } virtual void keterangan() { cout << keterangan() pada Makhluk... << endl; } }; class Mamalia : public Makhluk { public : { cout << informasi () pada mamalia... << endl; } void keterangan() { cout << keterangan() pada Mamalia... << endl; } }; class Sapi : public Mamalia { public : void informasi() { cout << informasi() pada Sapi... << endl; } void keterangan() { cout << keterangan() pada Sapi... << endl; } }; void main()
26
informasi() pada Makhluk keterangan() pada Mamalia ----------informasi() pada Makhluk keterangan() pada Mamalia
Pada program diatas mula-mula terdapat obyek berkelas Mamalia dan Sapi dan pointer yang menunjuk ke kelas Makhluk. Pointer diatur agar menunjuk ke obyek dinamis berkelas Mamalia. Suatu fungsi anggota informasi() dipanggil dari pointer, ternyata yang ditampilkan adalah fungsi anggota dari kelas Makhluk. Tetapi tidak demikian dengan halnya dengan keterangan(), Oleh karena keterangan diperlakukan sebagai fungsi virtual. Pada contoh program 6.1 tidak ada penciptaan obyek berkelas Makhluk yang ada adalah penciptaan pointer ke kelas Makhluk. Pada keadaan ini fungsi virtual tersebut menjadi tidak berguna. Untuk itulah kita harus membuat sebuah virtual murni. Perhatikan contoh berikut ini : //*----------------------------------------------------------------------* //* Contoh 6.2 : Untuk memeperlihatkan funsi Virtual murni * //*----------------------------------------------------------------------* #include <iostream.h> #include <conio.h> class Makhluk { public : virtual void keterangan() = 0; // fungsi virtual murni }; class Mamalia : public Makhluk { public : void keterangan() { cout << keterangan() pada Mamalia... << endl; } }; class Sapi : public Mamalia { public : void keterangan() { cout << keterangan() pada Sapi... << endl; } }; void main() { clrscr(); Mamalia mamalia; // definisi obyek mamalia Sapi sapi_sumba; // definisi obyek sapi_sumba Makhluk *binatang; // definisi obyek ke pointer berkelas makhluk binatang = &mamalia; // Menunjuk ke obyek mamalia binatang keterangan(); cout << ----------- << endl; binatang = &sapi_sumba; // Menunjuk ke obyek sapi_sumba binatang keterangan(); }
Hasil eksekusi :
27
28
Template Fungsi dan Kelas Template sering juga disebut sebagai cetak biru, berfungsi seperti menduplikasi sesuatu dengan cetakan. Template fungsi sangat bermanfaat untuk fungsi-fungsi yang menangani tugas yang sama dan berbeda hanya pada tipe data. Contoh program template fungsi : //*--------------------------------------* //* Contoh 7.1 : Template Fungsi * //*--------------------------------------* #include <iostream.h> #include <conio.h> // awal Template template <class T> void tukar (T &x, T &y) { T tmp; tmp = x; x = y; y = tmp; } // akhir template // prototipe fungsi void tukar (int &x, int &y); void tukar (double &x, double &y); void main() { clrscr(); double x = 17.777; double y = 15.555; cout << x = << x << y = << y << endl; tukar(x, y); cout << x = << x << y = << y << endl; int a = 55; int b = 77; cout << a = << a << b = <<b << endl; tukar(a, b); cout << a = << a << b = << b << endl; } Hasil eksekusi :
Seperti halnya fungsi biasa, template fungsi juga dapat di overloading. Hal ini berarti memungkinkan pemrogram membuat sejumlah template fungsi dengan nama yang sama. Perhatikan contoh program berikut : //*---------------------------------------------------------------* //* Contoh 7.2 : Overloading terhadap template fungsi * //*---------------------------------------------------------------* #include <iostream.h> #include <conio.h> // template fungsi template <class T> T maks(T data [ ], int jum_elemen) { T nilai_terbesar = data [ 0 ]; // data pertama for (int i = 1; i < jum_elemen; i ++) if (data [ i ] > nilai_terbesar) nilai_terbesar = data [ i ]; return(nilai_terbesar); } template <class T> T maks( T x, T y) { return ( (x > y) ? x : y ); } // Prototipe fungsi int maks(int, int); double maks(double, double); int maks(int [ ], int); float maks(float [ ], int); void main()
29
} Pada contoh diatas terdapat template fungsi dengan nama yang sama (yaitu maks). Namun argumen kedua template berbeda (ada yang melibatkan array dan ada yang tidak). Template juga dapat diterapkan pada kelas. Dalam hal ini template dipakai untuk mendeklarasikan anggota data dan juga fungsi-fungsi anggota kelas. Yang pada dasarnya hampir sama dengan template pada fungsi Friend Sebagai Teman Fungsi friend adalah fungsi bukan anggota kelas yang dapat mengakses anggota kelas. Fungsi seperti ini dipakai untuk mengakses anggota kelas baik yang bersifat prifat maupun terproteksi (protected). Perhatikan conttoh berikut : //*-----------------------------------------------------------------------* //* Contoh 7.4 : Fungsi friend untuk mengakses sebuah kelas * //* ----------------------------------------------------------------------* #include <iostream.h> #include <conio.h> #include <string.h> class Mahasiswa { private : long nomor_induk; char nama[35]; char jurusan[20]; public : Mahasiswa(); void inisialisasi(long no_induk, char *nama, char *jurusan); friend void tampilkan_data(Mahasiswa mhs); }; void main() { clrscr(); Mahasiswa mhs; Mhs.inisialisasi(9200012, Baharudin, Teknik Elektro); tampilkan_data(mhs) } // Definisi fungsi anggota Mahasiswa::Mahasiswa() { nomor_induk = 0; strcpy(nama, ); strcpy(jurusan, ); } void Mahasiswa::inisialisasi(long no_induk, char *nama, char *jurusan); { Mahasiswa::nomor_induk = no_induk; strcpy(Mahasiswa::nama, nama); strcpy(Mahasiswa::jurusan, jurusan); } // Definisi fungsi friend void tampilkan_data(Mahasiswa mhs) { cout << Nomor : << mhs.nomor_induk << endl; cout << Nama : << mhs.nama << endl; cout << Jurusan : << mhs.jurusan << endl; } Hasil eksekusi :
Fungsi tampilkan_data() pada kelas Mahasiswa dideklarasikan sebagai fungsi friend. Dengan demikian fungsi ini dapat mengakses data seperti nomor_induk. Perhatikan saat fungsi idefinisikan. Fungsi ini berkedudukan sebagai fungsi bias, bukan sebagai fungsi anggota.
30
Obyek dapat disimpan ke dalam file. Dengan cara merekam dan membacanya kembali. Obyek dapat direkam ke dalam file dengan menggunakan fungsi anggota write(). Perhatikan contoh berikut : //*------------------------------------------------* //* Contoh 8.1 : Menyimpan obyek ke file * //*------------------------------------------------* #include <iostream.h> #include <conio.h> #include <fstream.h> #include <string.h> #include <ctype.h> #include <stdlib.h> class buku { private : char kode[10]; char judul[35]; char pengarang[25]; int jumlah; public : void entri_buku(); }; void rekam_buku(Buku buku); void main() { char tmp[15]; clrscr(); cout << Merekam Data Buku << endl; cout << endl; cout << Kode :; cin.getline(kode, sizeof(kode)); cout << Judul :; cin.getline(judul, sizeof(judul)); cout << Pengarang :; cin.getline(pengarang, sizeof(pengarang)); cout << Jumlah :; cin.getline(tmp, sizeof(tmp)); jumlah = atoi(tmp); } // Untuk merekam data buku ke file void rekam_buku(Buku buku) { char jawab; // Buka modus penambahan ofstream file_buku(BUKU.DAT, ios::app); for ( ; ; ) { buku.entri_buku(); file_buku.write(char *)&buku, sizeof(buku)); // Pertanyaan untuk mengulang cout << endl; cout << Memasukkan data lagi (Y/T) : ; do { jawab = toupper(getch()); } whille ( !((jawab == Y) || (jawab == T)) ); cout << jawab << endl; if (jawab == T) break; } file_buku.close(); // Tutup file } Hasil eksekusi :
Merekan Data Buku Kode Judul Pengarang Jumlah : N00001 : Pemrograman C++ : Abdul Kadir :3
31
Membaca data pada obyek file dapat dilakukan dengan menggunakan fungsi anggota read(). Perhatikan contoh berikut : //*-----------------------------------------------------* //* Contoh 8.2 : Membaca data obyek dari file * //*-----------------------------------------------------* #include <iostream.h> #include <conio.h> #include <fstream.h> class buku { private : char kode[10]; char judul[35]; char pengarang[25]; int jumlah; public : void info_buku(); }; void baca_buku(Buku buku); void main() { Buku buku_perpustakaan; baca_buku(buku_perpustakan); } void Buku::info_buku() { cout << Kode : << kode << endl; cout << Judul : << judul << endl; cout << Pengarang : << pengarang << endl; cout << Jumlah : << jumlah << endl; cout << endl; } // Untuk merekam data buku ke file void baca_buku(Buku buku) { ifstream file_buku(BUKU.DAT, ios::app); cout << Daftra Buku << endl; cout << endl; file_buku.read(char *)&buku, sizeof(buku)); whille ( !file_buku.eof() ) { buku.info_buku(); file_buku.read(char *)&buku, sizeof(buku)); } file_buku.close(); // Tutup file }
Hasil eksekusi :
Kode
: F00001
Jumlah
:7
32
Senarai berantai (Linked List) merupakan contoh struktur data sederhana yang menggunakan pemakaian memori secara dinamis. Perhatikan contoh lengkap senarai berantai berikut : //*-------------------------------------* //* Contoh 9.1 : Senarai berantai * //*-------------------------------------* #include <iostream.h> #include <iomanip.h> #include <string.h> #include <conio.h> struct Simpul { char nama[35]; char telepon[15]; Simpul *lanjutan; }; class Senarai { private : Simpul *pertama; Simpul *pendahulu; // Digunakan untuk penghapusan Simpul *cari(char *nama); public: Senarai(); ~Senarai(); int tambah(char *nama, char *telepon, char *alamat); void tampil(); void tampil(char *nama); int hapus(char *nama); }; void main() { clrscr(); Senarai daftar; daftar.tambah("Amiruddin","675834"); daftar.tambah("Esti Pangestu","685834",); daftar.tambah("Udinsah","675846"); daftar.tambah("Sita Dewi","677734"); daftar.tambah("Gusti Randa","676835"); daftar.tampil(); daftar.tampil("Udin"); daftar.hapus("Udinsah"); daftar.tampil(); } Senarai::Senarai() { pertama = NULL; } Senarai::~Senarai() { // Hapus seluruh simpul Simpul *simpul_dihapus; while (pertama != NULL) { simpul_dihapus = pertama; pertama = pertama->lanjutan; delete simpul_dihapus; } } //*-----------------------------------------------------------------------------* //* tambah() * //* Menambah data ke senarai * //* Nilai balik : 0 Data tidak berhasil ditambahkan (heap penuh) * //* 1 Data berhasil ditambahkan * //*-----------------------------------------------------------------------------* int Senarai::tambah(char *nama, char *telepon, char *alamat) { Simpul *baru; baru = new Simpul; if (baru) { baru->lanjutan = pertama;
33
34
35
DAFTAR TELEPON : Gusti Randa676835 Sita Dewi677734 Udinsah...675846 Esti Pangestu..685834 Amirudin.675834 DAFTAR TELEPON UDIN : Udinsah...675846 Amirudin.675834suatu struktur yang terdiri sejumlah simpul dengan Dalam terminologi struktur data, sebuah pohon (tree) adalah
karateristik sebagai berikut : 1. Ada sebuah simpul yang berkedudukan sebagai puncak (disebut akar atau root). Semua simpul dapat ditelusuri dari DAFTAR TELEPON : simpul ini. Gusti Randa676835 2. setiap simpul mempunyai lintasan yang unuk terhadap akar. Perhatikan Sita Dewi677734 contoh program lengkap tentang pohon biner. Esti Pangestu..685834 //*--------------------------------* //* Contoh 9.2 : Pohon biner * Amirudin.675834 //*--------------------------------* #include <iostream.h> #include <string.h> #include <conio.h> // Struktur simpul pohon struct SimpulPohon { SimpulPohon *induk; // Menunjuk ke induk SimpulPohon *kiri; // Menunjuk ke anak kiri SimpulPohon *kanan; // Menunjuk ke anak kanan char data; }; class PohonBiner { private : SimpulPohon *akar; int tambah(SimpulPohon *orang tua, SimpulPohon *baru); SimpulPohon *cari(SimpulPohon *simpul, char data); void hapus_semua_simpul(SimpulPohon *simpul); void tampil(SimpulPohon *simpul); public : PohonBiner(); // Konstruktor ~PohonBiner(); // Destruktor int tambah(char data); void tampil(); int hapus(char data); int cari(char data); }; void main() { clrscr(); char data[ ] = CARKDUPBENXZS; PohonBiner pohon; // Bentuk keadaan awal pohon biner for (int i = 0; i < strlen(data); i ++ ) !pohon.tambah(data[ ]); cout << Daftar Perintah : << endl; cout << + diikuti karakter menambah data << endl; cout << - diikuti karakter menghapus data << endl; cout << ? diikuti karakter mencari data << endl; cout << L menampilkan pohon biner << endl; cout << S selesai << endl; char perintah, karakter; do { cout << Perintah : ; cin >> perintah; switch(perintah) { case + : cin >> karakter; pohon.tambah(karakter);
36
37
38
39
Daftar Perintah : + diikuti karakter menambah data - diikuti karakter menghapus data ? diikuti karakter mencari data L menampilkan pohon biner S selesai Perintah : L ABCDEKNPRSUXZ Perintah : A A ada pada pohon Perintah : M M tidak ada pada pohon Perintah : L ABCDEKMNPRSUXZ Tugas Praktikum : : -D Perintah Buat program menggunakan senarai berantai (lihat contoh program 9.1). Perintah : L Ubah program diatas. Dimana data input dimasukkan lewat keyboard. ABCDEKMNPRSUXZ (simpan dengan nama tugoop9.cpp)