• Tidak ada hasil yang ditemukan

Pemrograman Berorientasi Objek

N/A
N/A
Protected

Academic year: 2017

Membagikan "Pemrograman Berorientasi Objek"

Copied!
51
0
0

Teks penuh

(1)

DIKTAT

PEMROGRAMAN BERORIENTASI OBYEK C++

DISUSUN UNTUK MENUNJANG

PERKULIAHAN PEMROGRAMAN BERORIENTASI

OBYEK

Disusun oleh

Yuli Praptomo PHS, S.Kom.

(2)

MODUL I PENGENALAN

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 :

- Encapulation

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 Bioalogi. 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 :

Meriam Benrteng Navarone

AlistaiMacLean

(3)

Pada contoh diatas terdapat struktur yang bernama buku, sebuah kelas (class) dapat dibuat seperti struktur, dengan mengantikan kata struct menjadi class ditambah baris yang berisi public diikuti tanda “ : “. Perhatikan contoh berikut :

Contoh program :

//*---* //* Contoh 1.2 : Sebuah kelas yang menggunakan * //* public * //*---* #include <iostream.h>

#include <conio.h> #include <string.h> class buku

{

public : //  Tambahan 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; }

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 privete

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 fungsi-fungsi 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 privete 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>

(4)

#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; }

};

void main() {

clrscr();

buku novel; // Pendefinisian obyek novel.inisialisasi ( “Meriam Benteng Navarone”,

“Alistair MacLean”,12 ); novel.info ();

}

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> #include <string.h> class buku

{

privete :

char judul[35]; char pengarang[25];

Judul

: Meriam Benteng Navarone

(5)

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, fiksi // Pendefinisian obyek // Memberi nilai kepada kedua obyek

novel.inisialisasi ( “Meriam Benteng Navarone”, “Alistair MacLean”,12 );

fiksi.inisialisasi ( “Jurassic Park”, Michael Crichton”, 3); // Menampilkan informasi yang terdapat pada kedua obyek novel.info ();

fiksi.info (); }

Hasil eksekusi :

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 ;

}

Judul

: Meriam Benteng Navarone

Pengarang

: Alistair MacLean

Jumlah Buku : 12

Judul

: Jurassic Park

(6)

void info () {

cout << “Judul : “ << judul << endl; cout << “Pengarang : “ << pengarang << endl; cout << “Jumlah Buku : “ << jumlah << endl; }

};

void main() {

clrscr();

buku novel, fiksi // Pendefinisian obyek // Memberi nilai kepada kedua obyek

novel.inisialisasi ( “Meriam Benteng Navarone”, “Alistair MacLean”,12 ); // Penugasan obyek

fiksi = novel;

// Tampilkan informasi obyek fiksi fiksi.info ();

}

Hasil eksekusi :

Cara pendefinisian fungsi anggota ada dua macam yakni cara pertama, fungsi anggota didefinisikan didalam deklarsi kelas. Bentuk kedua, pada kelas hanya terdapat fungsi anggota (prototipe). Definisi untuk kedua fungsi anggota pada kelas buku ditulis menjadi :

void buku::inisialisasi ( char *judul, char *pengarang, int *jumlah)

{

strcpy(judul, Judul );

strcpy(pengarang, Pengarang ); jumlah = Jumlah ;

}

void buku::info () {

cout << “Judul : “ << judul << endl;

cout << “Pengarang : “ << pengarang << endl; cout << “Jumlah Buku : “ << jumlah << endl;

}

perlu diketahui, pada penulisan fungsi seperti buku::inisilaisasi(), dengan sendirinya anggota data kelas buku dikenali pada fungsi tersebut.

Contoh program :

//*---* //* Contoh 1.6 : Altenatif lain penulisan anggota * //*---* #include <iostream.h>

#include <conio.h> #include <string.h> class buku

{

privete :

char judul[35]; char pengarang[25]; int jumlah;

public :

Judul

: Meriam Benteng Navarone

(7)

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(judul, Judul );

strcpy(pengarang, Pengarang ); jumlah = Jumlah ;

}

void buku::info () {

cout << “Judul : “ << judul << endl;

cout << “Pengarang : “ << pengarang << endl; cout << “Jumlah Buku : “ << jumlah << endl;

}

Hasil eksekusi :

Nama parameter (argumen) dan data anggota yang digunakan berbeda (perbedaan terletak pada huruf awalnya). Hal seperti ini tidak menimbulkan kerancuan.berbeda halnya kalau nama parameter fungsi dan nama anggota data kelasternyata sama.

Kalau nama parameter dana anggota data kelas sama dengan nama parameter, nama aanggota data tetap bisa diakses. Pengaksesannya melalui operator resolusi lingkup ( :: ), dengan format :

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()

Meriam Benrteng Navarone

AlistaiMacLean

12

(8)

{

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 *

void beri_tanggal(int tanggal, int bulan, int tahun); void info();

int info_tanggal() {return tanggal }; int info_bulan() {return bulan}; int info_tahun() {return tahun}; };

void main(); {

clrscr();

Tanggal tanggal_lahir;

tanggal_lahir.beri_tanggal(25, 6, 1991); tanggal_lahir.info();

cout << tanggal_lahir.info_tanggal() << ‘ – ‘ << tanggal_lahir.info_bulan() << ‘ – ‘ << tanggal_lahir.info_tahun();

}

void Tanggal::beri_tanggal(int tanggal, int bulan, int tahun) {

Tanggal::tanggal = tanggal; Tanggal::bulan = bulan; Tanggal::tahun = tahun; }

void Tanggal::info() {

cout << setfill(‘0’);

(9)

<< ‘ / ‘ << setw(2) << bulan << ‘/ ’ << tahun << endl;

cout << setfill( ‘ ‘); }

Hasil eksekusi :

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.

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)

Tanggal

: 28/11/1982

(10)

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 a.info();

Kompleks b; // Mendefinisikan obyek b b.info();

}

// 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……….

real

= 5.2

(11)

Hasil didepan menunjukan bahwa konstruktor dijalankan dengan sendirinya saat obyek a dan b diciptakan melalui pernyataan :

Kompleks a; Kompleks b;

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);

Judul

: Siaga Merah

Pengarang

: Alistair MacLean

(12)

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 : JudulPengarang : Judul KOSONG: Pengarang KOSONG

Jumlah : 0

Judul : Partisan

Pengarang : Pengarang KOSONG Jumlah : 0

Judul : Matahari Terbit Pengarang : Michael Crichton Jumlah : 0

(13)

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.

2.2. Destruktor

Destruktor adalah fungsi anggota kelas yang akan dijalankan secara otomatis pada obyek yang akan sirna. Nama destruktor sama dengan nama konstruktor, hanya saja diawali dengan sebuah karakter tak-berhingga (~). Perhatikan contoh program berikut :

//*---* //* Contoh 2.4 : Contoh Destruktor * //*---* #include <iostream.h>

#include <conio.h> class Bilangan {

private : int i; public :

Bilangan(); // Konstruktor ~Bilangan(); // Destruktor void info_data();

};

void main() {

clrscr(); Bilangan x; x.info_data(); Bilangan y; y.info_data();

cout << “ Fungsi main() berakhir...” << endl; }

Bilangan::Bilangan() {

cout << “Konstruktor dijalankan...” << endl; i = 55;

}

Bilangan::~Bilangan() {

cout << “Destruktor dijalankan...” << endl; }

void Bilangan::info_data() {

cout << “ i = “ << i << endl << endl; }

Hasil eksekusi :

Konstruktor dijalnkan…

i = 55

Konstruktor dijalankan…

i = 55

(14)

Tampak bahwa destruktor dari masing-masing obyek dengan sendirinya dijalankan saat fungsi

main() berakhir.

Konstruktor dan destruktor sangat bermanfaat untuk melakukan pengalokasian memori secara dinamis dan pendealokasiannya(membebaskan memori).

Contoh program :

//*---* //* 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() {

clrscr();

Mobil sedan(“charade classy”, 1300, 5); Mobil picup(“datsun”, 1000, 2); sedan.keterangan();

picup.keterangan(); }

Mobil::Mobil( char *nama, int cc_mesin, int jumlah_pintu) {

nama = new char [25]; strcpy(nama, nama_mobil); cc_mesin = cc;

jumlah_pintu = jumlah_pintu; }

Mobil::~Mobil() // Destruktor {

delete [ ] nama; }

void Mobil::keterangan() {

cout << ”Informasi mobil : “ << endl;

cout << “Nama : “ << nama << endl; cout << “CC mesin : “ << cc_mesin << endl; cout << “Jumlah pintu: “ << jumlah_pintu << endl; cout << endl;

}

Hasil eksekusi :

Infomasi mobil :

Nama : charade classy CC mesin : 1300

Jumalah pintu : 5

(15)

Pada contoh program diatas, anggota data nama merupakan pointer yang menunjuk ke tipe

char. Lokasi yang ditunjukkan dialokasikan di heap. Oleh karena obyek yang diciptkan akan menggunakan lokasi di heap, obyek juga harus membenaskan kembali kalau obyek akan sirna.

Tugas Praktikum :

Buatlah program untuk memasukkan tanggal lahir anda dan teman kelompok anda, gunakan kontruktor dan destruktor.

(16)

MODUL III

KELAS DAN OBYEK LANJUTAN

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;

(17)

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 :

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 :

Judul

: Judul KOSONG

Pengarang

: Pengarang KOSONG

Jumlah buku : 0

Judul

: The Eagle Has Flown

Pengarang

: Jack Higgis

Jumlah buku : 1

Judul

: Pemrograman C++

(18)

Oleh karena program diatas terdapat pengalokasian dinamis, pernyataan delete diperlukan (yaitu untuk mendealokasikan memori di heap).

Program dibawah memberikan gambaran penciptaan sejumlah obyek dinamis yang ditampilkan oleh pointer.

//*---* //* Contoh 3.5 : Pointer yang menunjuk ke sejumlah obyek dinamis * //*---* #include <iostrream.h>

#include <conio.h> #include “buku.h” void main() {

clrscr();

Buku *pbuku; // Pointer pbuku = new Buku[5];

for (int i = 0; i < 5; i ++) pbuku[i].info();

delete [ ] pbuku; // Hapus 5 Obyek }

Suatu obyek juga dapat menjadi parameter fungsi. Dalam hal ini ada tiga kemungkinan untuk melewatkan obyek sebagai parameter yaitu :

- Melewatkan obyek berdasarkan nilai - Melewatkan obyek sebagai pointer - Melewatkan obyek sebagai referensi Contoh fungsi yang melewatkan obyek sebagai nilai :

void info_buku(Buku b) {

cout << “INFORMASI BUKU” << ‘\n’ << endl; b.info();

}

Contoh fungsi yang melewatkan obyek sebagai pointer : void info_buku(Buku *b)

{

cout << “INFORMASI BUKU” << ‘\n’ << endl; (*b).info();

} atau

void info_buku(Buku *b) {

cout << “INFORMASI BUKU” << ‘\n’ << endl; b->info();

}

Contoh fungsi yang melewatkan obyek sebagai referensi : void info_buku(Buku &b)

{

cout << “INFORMASI BUKU” << ‘\n’ << endl; b.info();

}

(19)

//*---* //* Contoh 3.6 : array dengan elemen berupa obyek * //*---*

Obyek dapat dijadikan sebagai nilai balik fungsi. Perhatikan contoh program berikut : //*---*

//* Contoh 3.7 : Menunjukan fungsi dengan nilai balik * //* berupa obyek *

Buah(int jum_apel = 0, int jum_jeruk = 0); void info_buah();

Buah tambah(Buah b2); };

void main() {

clrscr();

Buah buah1 (20, 5); Buah buah2 (12, 4); Buah buah3;

buah3 = buah1.tambah(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::tambah(buah b2) {

(20)

}

Hasil eksekusi :

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 :

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) ();

(21)

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 :

Pada program diatas terlihat bahwa dengan menggunakan pointer yang menunjuk ke fungsi anggota, pointer dapat diatur untuk menunjuk ke fung_1() dan fung2() secara bergantian.

Tugas Praktikum

Buatlah sebuah program untuk menjumlahkan tanggal lahir anda dengan teman anda menggunakan aturan pointer ke fungsi anggota. (simpan dengan nama tuoop3.cpp ).

Via fungsi anggota

fung_1() dijalankan…

fung_2() dijalankan…

5 + 8 = 13

Via pointer ke fungsi anggota

fung_1() dijalankan…

(22)

MODUL IV

OVERLOADING TERHADAP OPERATOR

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

Sizeof Operator untuk memperoleh ukuran data sizeof(int)

Untuk memahami gambaran tentang overloading terhadap operator biner (operator dengan dua operand), perhatikan program berikut :

//*---* //* contoh 4.1 : Menunjukan overloading terhadap operator + * //*---*

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; return(tmp);

}

Hasil eksekusi :

(23)

Contoh program diatas menyerupai contoh program 3.7 pada Bab III. Perbedaan utamanya, kata tambah diganti dengan operator +.

Dalam bentuk yang umum, overloading terhadap oparator biner berupa :

Program 4.1 hanya bisa menanggani bentuk : obyek3 = obyek1 + obyek2 tetapi bila anda menginginkan bentuk seperti : obyek3 = obyek1 + 5 yang berarti semua anggota data pada obyek1

ditambah dengan 5. perhatikan contoh program berikut :

//*---* //* Contoh 4.2 : untuk menunjukan overloading terhadap * //* operator + dengan bentuk : * //* obyek + konstanta * //*---* #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); Buah operator + (int tambahan); };

void main() {

clrscr();

Buah buah1 (20, 5); Buah buah2;

cout << “obyek buah1 “ << endl; buah1.info_buah();

buah2 = buah1 + 5;

cout << “obyek buah2 “ << endl; buah2.info_buah();

buah2 = buah1 + buah1;

cout << “obyek buah2 “ << endl; buah2.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

(24)

tmp.apel = apel + b2.apel; tmp.jeruk = jeruk + b2.jeruk; return(tmp);

}

Buah Buah::operator + (int tambahan) {

Buah tmp; // Obyek sementara tmp.apel = apel + tambahan; tmp.jeruk = jeruk + tambahan; return(tmp);

}

Hasil eksekusi :

Contoh berikut menunjukkan bentuk overloading terhadap operator unary, yaitu operator yang mempunyai sebuah operand.

//*---* //* Contoh 4.3 : menunjukan overloading terhadap operator * //* ++ dan -- *

Buah(int jum_apel = 0, int jum_jeruk = 0); void info_buah();

viod operator ++ (); void operator -- (); };

void main() {

clrscr();

Buah paket (20, 5);

cout << “Mula-mula : “ << endl; paket.info_buah();

++paket; ++paket;

cout << “Setelah dinaikkan 2x : “ << endl; paket.info_buah();

--paket;

cout << “Setelah diturunkan 1x : “ << endl; paket.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 ++ ()

(25)

{

++apel; ++jeruk; }

Buah Buah::operator -- ()

{

--apel; --jeruk; }

Hasil eksekuisi :

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 > * //*---* #include <iostream.h>

#include <conio.h> class harga

{

obyek buah1

Jumlah apel = 20 Jeruk = 5

Setelah dinaikkan 2x :

(26)

private :

long harga_barang; float persen_diskon; public :

Harga(int = 0, float – 0.0) void info_harga(); int operator < (Harga); };

void main() {

clrscr();

Harga barang1(10000, 15.0); Harga barang2(10000, 10.0); Harga barang3(10000, 12.0); if (barang1 < barang2)

cout << “barang1 lebih murah dari barang2” << endl; else

cout << “barang1 tidak lebih murah dari barang2” << endl; if (barang2 < barang3)

cout << “barang2 lebih murah dari barang3” << endl; else

cout << “barang2 tidak lebih murah dari barang3” << endl; }

Harga::Harga(int harga, float diskon) {

harga_barang = harga; persen_diskon = diskon; }

void Harga::info_harga() {

cout << “ Harga = “ << harga-barang << endl; cout << “Diskon = “ << persen_diskon

<< “%\n” << endl; }

int Harga::operator < (Harga x) {

long harga = harga_barang – persen_diskon / 100 * harga_barang; long harga_x = x.harga_barang –

x.persen_diskon / 100 * x. harga_barang; return (harga < harga_x) ? 1 : 0 );

}

Hasil eksekusi :

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;

(27)

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; buah1.info_buah();

cout << “obyek buah2 “ << endl; buah2.info_buah();

buah2 += buah1;

cout << “obyek buah2 “ << endl;

cout << “setelah : buah2 += buah1” << endl; buah2.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 b) {

apel += b.apel; jeruk += b.jeruk; return(*this); }

Hasil eksekusi :

Tugas Praktikum :

Buatlah program dengan menggunakan overloding untuk menghitung penjumlahan tanggal lahir anda dengan teman anda. (simpan dengan nama tuoop4.cpp)

obyek buah1

Jumlah apel = 20 Jeruk = 5

obyek buah2

Jumlah apel = 12 Jeruk = 4

Obek buah2

(28)

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 {

public :

void info_turunan() {

cout << “info_turunan() dijalankan...” << endl; }

};

void main() {

clrscr(); Turunan anak; anak.info_basis(); anak.info_turunan(); }

Hasil eksekusi :

Pada contoh program diatas terdapat kelas bernama Basis dan Turunan. Dalam hal ini Basis

adalah kelas dasar sedang Turunan adalah kelas turunan. Kelas Turunan mewariskan sifat-sifat dari kelas Basis.

Selain menggunakan public dan private sebagai penentu akses kita dapat juga menggunakan protected. Perhatikan contoh berikut :

//*---* //* Contoh 5.2 : Penggunaan Protected * //*---* #include <iostream.h>

#include < conio.h>

(29)

class Basis {

protected : int alpha; int bravo; public :

void info_basis() {

cout << “info_basis() dijalankan...” << endl; }

};

class Turunan : public Basis {

public :

void inisialisasi(int a, int b) { alpha = a; bravo = b; } void info_turunan()

{

cout << “alpha =” << alpha

<< “ bravo = “ << bravo << endl; }

};

void main() {

clrscr(); Turunan anak;

anak.inisialisasi(2, 5); // alpha -> 2, bravo -> 5 anak.info_turunan();

}

Hasil eksekusi :

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]; int usia; public :

orang(char *nama, int usia); void info_orang();

};

class Pegawai : public Orang {

private :

char bagian[25]; int nomor_pegawai; public :

Pegawai(char *nama, int usia,

char *bagian, int nomor_pegawai);

(30)

void info_pegawai(); };

class Manajer : public Pegawai {

private :

char mobil[30]; public :

Manajer(char *nama, int usia,

char *bagian, int nomor_pegawai,

Manajer kabag_edp(“Udin”, 35, “EDP”, 11885, “Sedan Larantuka”); kabag_edp.info_manajer();

}

Orang::Orang(char *nama, int usia) {

strcpy(Orang::nama, nama); Orang::usia = usia;

}

void Orang::info_orang() {

cout << “Nama : “ << nama << endl; cout << “Usia : “ << usia << endl; }

Pegawai::Pegawai(char *nama, int usia,

char *bagian, int nomor_pegawai); Orang(nama, usia);

{

strcpy(Pegawai::bagian, bagian);

Pegawai::nomor_pegawai = nomor_pegawai; }

void Pegawai::info_pegawai() {

info_orang();

cout << “Bagian : “ << bagian << endl; cout << “Nomor Peg. : “ << nomor_pegawai << endl; }

Manajer::Manajer(char *nama, int usia,

char *bagian, int nomor_pegawai, char *mobil);

Pegawai(nama, usia, bagian, nomor_pegawai) {

cout << “Mobil : “ << mobil << endl; }

Hasil eksekusi :

Nama

: Udin

Usia

: 35

Bagian

: EDP

Nomor Peg.

: 11885

(31)

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; }

(32)

{

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; }

void PaketBukuDisket::info_paket() {

info_buku(); info_disket();

cout << “Harga total : “ << harga << endl; }

Hasil eksekusi :

Tugas Praktikum :

Buatlah program untuk menghitung total nilai 3 mata praktikum dengan menggunakan pewarisan berganda.

(simpan dengan nama tugoop5.cpp)

Judul buku

: C++

Pengarang

: Alakadabra

Harga buku

: 25000

(33)

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() {

clrscr();

(34)

Makhluk *binatang; // definisi obyek ke pointer berkelas makhluk binatang = &mamalia; // Menunjuk ke obyek mamalia

binatang informasi(); binatang keterangan(); cout << “---“ << endl;

binatang = &sapi_sumba; // Menunjuk ke obyek sapi_sumba binatang informasi();

binatang keterangan(); }

Hasil eksekusi :

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;

informasi() pada Makhluk…

keterangan() pada

Mamalia…

(35)

binatang = &sapi_sumba; // Menunjuk ke obyek sapi_sumba binatang keterangan();

}

Hasil eksekusi :

Bagian dari kelas yang dapat dijadikan virtual adalah fungsi anggota dari destruktor. Destroktor virtual dipakai kalau suatu kelas perlu untuk menghapus obyek dari kelas turunan berdasarkan pointer yang menunjuk kekelas dasar.

Perhatikan contoh program berikut : //*---* //* Contoh 6.3 : Destruktor virtual * //*---* #include <iostream.h>

#include <conio.h> #include <string.h> class TrahKeluarga {

protected :

char *nama_keluarga; public :

TrahKeluarga(char *nama) {

nama_keluarga = new char[strlen(nama) + 1]; strcpy(nama_keluarga, nama);

}

virtual ~TrahKeluarga() {

cout << “Destruktor di TrahKeluarga...” << endl; delete [ ] nama_keluarga; // Bebaskan memori }

virtual void info() = 0; // Fungsi virtual murni };

class Keturunan : public TrahKeluarga {

private :

char *nama_depan; public :

Keturunan(char *nama_awal, char *nama_kel); TrakKeluarga(nama_kel)

{

nama_depan = new char [strlen(nama_depan) + 1]; strcpy(nama_depan, nama_awal);

}

~Keturunan() {

cout << “Destruktor di Keturunan...” << endl; delete [ ] nama_depan; // Bebaskan memori }

void info() {

keterangan() pada Mamalia…

(36)

cout << nama_depan << ‘ ‘ << nama_keluarga << endl; }

};

void main() {

clrscr();

TrahKeluarga *anak_pertama = new Keturunan(“Umar”, “Wiratmaja”); Anak_pertamainfo();

Delete anak_pertama; }

Hasil eksekusi :

Program diatas mula-mula menciptakan pointer yang menunjuk ke obyek kelas dasar (TrahKeluarga). Kemudian pointer ini menunjuk ke obyek yang dialokasikan pada heap. Obyek yang ditunjuk berkelas Keturunan. Setelah informasi dari obyek ditampilkan, obyek dihapus melalui delete.

Tugas Praktikum :

Buat program dengan menggunakan virtual destruktor untuk tugas minggu V. (simpan dengan nama tugoop6.cpp)

Umar Wiratmaja

(37)

BAB VII

TEMPLATE FUNGSI, TEMPLATE KELAS DAN FRIEND SEBAGAI TEMAN

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 templatefungsi dengan nama yang sama. Perhatikan contoh program berikut :

//*---* //* Contoh 7.2 : Overloading terhadap template fungsi * //*---* #include <iostream.h>

#include <conio.h>

x = 17.777

y = 15.555

x = 15.555

y = 17.777

a = 55 b = 77

(38)

// 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()

{

clrscr(); int i = 5, j = 6;

cout << maks(i, j) << endl; double x = 5, j = 6;

cout << maks(x, y) << endl; int a [ ]= {1, 4, 5, 7, 0); cout << maks(a, 5) << endl;

double b [ ] = {17.7, 5.55, 6.66, 8.88, 1.11}; cout << maks(b, 5) << endl;

}

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 :

(39)

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.

Tugas Praktikum :

Buatlah sebuah program untuk membalik kata dengan menggunakan template. (simpan dengan nama tugoop7.cpp)

Nomor

: 9200012

Nama

: Baharudin

(40)

MODUL VIII OPERASI FILE

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 * //*---*

void rekam_buku(Buku buku); void main()

{

char tmp[15]; clrscr();

cout << “ Merekam Data Buku” << endl; cout << endl;

cout << “Kode : “ ; 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;

(41)

}

file_buku.close(); // Tutup file }

Hasil eksekusi :

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;

Merekan Data Buku

Kode

: N00001

Judul

: Pemrograman C++

Pengarang

: Abdul Kadir

Jumlah

: 3

Merekan Data Buku

Kode

: F00001

Judul

: Rumahku Istanaku

Pengarang

: Marga T

(42)

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 :

Tugas praktikum :

Buatlah program untuk memasukkan data mata kuliah dan membacanya dengan menggunakan operasi file.

(simpan dengan nama tugoop8.cpp)

Daftar Buku

Kode

: N00001

Judul

: Pemrograman C++

Pengarang

: Abdul Kadir

Jumlah

: 3

Daftar Buku

Kode

: F00001

Judul

: Rumahku Istanaku

Pengarang

: Marga T

(43)

MODUL IX

SENARAI BERANTAI DAN POHON BINER

Senarai berantai (Linked List) merupakan contoh struktur data sederhana yang menggunakan pemakaian memori secara dinamis. Perhatikan contoh lengkap senarai berantai berikut :

//*---* 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); };

pertama = NULL; }

Senarai::~Senarai() {

// Hapus seluruh simpul Simpul *simpul_dihapus; while (pertama != NULL) {

simpul_dihapus = pertama; pertama = pertama->lanjutan; delete simpul_dihapus; }

(44)

//*---* //* 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; strcpy(baru->nama, nama); strcpy(baru->telepon, telepon); strcpy(baru->alamat, alamat); pertama = baru;

return(1); //* Menampilkan daftar telepon berdasarkan suatu panggilan nama * //* ---* void Senarai::tampil(char *nama)

{

Simpul *ptr_data = pertama; char data_nama[35]; char dicari[35]; strcpy(dicari, nama); strupr(dicari);

cout << setiosflags(ios::left) << setfill('.');

cout << endl << "DAFTAR TELEPON " << dicari << " : " << endl;

while (ptr_data != NULL) {

strcpy(data_nama,ptr_data->nama); strupr(data_nama);

if (strstr(data_nama, dicari))

cout << setw(36) << ptr_data->nama << setw(10) << ptr_data->telepon << ptr_data->alamat << endl; ptr_data = ptr_data->lanjutan; }

cout << resetiosflags(ios::left) << setfill(' '); }

//*---* //* tampil() * //* Menampilkan isi seluruh simpul pada senarai berantai * //*---* void Senarai::tampil()

{

Simpul *ptr_data = pertama;

cout << setiosflags(ios::left) << setfill('.'); cout << endl << "DAFTAR TAMU : " << endl; while (ptr_data != NULL)

{

cout << setw(36) << ptr_data->nama << setw(10) << ptr_data->telepon

(45)

ptr_data = ptr_data->lanjutan; }

cout << resetiosflags(ios::left) << setfill(' '); }

//*---* //* cari() * //* Nilai Balik : * //* NULL  Data ketemu * //* Bukan NULL  Data tak ketemu * //*---* Simpul *Senarai::cari(char *nama) {

Simpul *ptr_data = pertama; pendahulu = NULL; while (ptr_data != NULL) {

if (strcmp(nama, ptr_data->nama) == 0) break;

pendahulu = ptr_data; ptr_data = ptr_data->lanjutan; }

return(ptr_data); }

//*---* //* hapus() * //* Menghapus suatu simpul berdasarkan suatu nama * //* Nilai Balik = 0 – data tidak ada * //* 1 – simpul berhasil dihapus * //*---* int Senarai::hapus(char *nama)

{

Simpul *posisi_data; posisi_data = cari(nama); if (posisi_data == NULL) return(0); // Data tak ada else

{

if (pendahulu == NULL) {

// Simpul yang akan dihapus adalah simpul yang pertama pertama = pertama->lanjutan;

} else {

// Bukan simpul yang pertama yang akan dihapus pendahulu->lanjutan = posisi_data->lanjutan; }

delete posisi_data; }

(46)

Hasil eksekusi :

Dalam terminologi struktur data, sebuah pohon (tree) adalah suatu struktur yang terdiri sejumlah simpul dengan karateristik sebagai berikut :

1. Ada sebuah simpul yang berkedudukan sebagai puncak (disebut akar atau root). Semua simpul dapat ditelusuri dari simpul ini.

2. setiap simpul mempunyai lintasan yang unuk terhadap akar. Perhatikan contoh program lengkap tentang pohon biner.

//*---* //* Contoh 9.2 : Pohon biner * //*---* #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();

DAFTAR TELEPON :

Gusti Randa………676835

Sita Dewi………677734

Udinsah..….………675846

Esti Pangestu………..685834

Amirudin….………675834

DAFTAR TELEPON UDIN :

Udinsah..….………675846

Amirudin….………675834

DAFTAR TELEPON :

Gusti Randa………676835

Sita Dewi………677734

Esti Pangestu………..685834

(47)

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); break;

case ‘-‘ :

cin >> karakter; pohon.hapus(karakter); break;

case ‘?’ :

cin >> karakter;

if (pohon.cari(karakter)); }while (perintah != ‘S’);

}

// Definisi fungsi anggota dan konstruktor PohonBiner::PohonBiner()

void PohonBiner:: hapus_sumua_simpul(SimpulPohon *simpul) {

if (simpul) {

(48)

delete simpul; int PohonBiner::tambah(char data)

{

SimpulPohon *simpul; Simpul = new SimpulPohon; simpulkiri = NULL; simpulkanan = NULL; simpulinduk = NULL; simpuldata = data; if (akar == NULL) {

akar = simpul; return(1);

int PohonBiner::tambah(SimpulPohon *orangtua, SimpulPohon *baru) {

if (!orangtuakiri) {

orangtuakiri = baru; baruinduk = orangtua; }

else

return(tambah(orangtuakiri, baru); }

else {

if (!orangtuakanan) {

orangtuakanan = baru; baruinduk = orangtua; }

else

return(tambah(orangtuakanan, baru); }

return(1); }

(49)

{

tampil(akar); cout<< endl; }

void PohonBiner::tampil(SimpulPohon *simpul) {

if (simpul) {

if (simpulkiri) tampil (simpulkiri); cout << simpul data;

if (simpulkanan tampil (simpulkanan); } int PohonBiner::hapus(char data)

{

SimpulPohon *simpul_dihapus; Simpul_dihapus = cari(akar, data); if (!simpul_dihapus == NULL)

return(0); //Data dicari tidak ketemu if (!simpul_dihapuskanan)

{

if (!simpul_dihapuskiri) {

// Simpul yang akan dihapus sebagai daun if (!simpul_dihapus == akar)

akar = NULL; else

if (simpul_dihapusindukkiri == simpul_dihapus) simpul_dihapusindukkiri = NULL;

// Simpul yang akan dihapus mempunyai anak if (simpul_dihapus == akar)

{

akar = simpul_dihapuskiri; akarinduk = NULL; }

else

if (simpul_dihapusindukkiri == simpul_dihapus) {

simpul_dihapusindukkiri = simpul_dihapus kiri; simpul_dihapuskiriinduk = simpul_dihapus induk; }

else {

simpul_dihapusindukkanan = simpul_dihapus kiri; simpul_dihapuskiriinduk = simpul_dihapus induk; }

} } else

(50)

{

// Simpul yang akan dihapus

// Mempunyai anak di sebelah kanan saja if (simpul_dihapus == akar)

{

akar = simpul_dihapuskanan; akarinduk = NULL;

} else

if (simpul_dihapusindukkiri == simpul_dihapus) {

simpul_dihapusindukkiri = simpul_dihapus kanan; simpul_dihapuskananinduk = simpul_dihapus induk; }

else {

simpul_dihapusindukkanan = simpul_dihapus kanan; simpul_dihapuskananinduk = simpul_dihapus induk; }

} else {

// Simpul yang dihapus memiliki dua buah sub pohon SimpulPohon *suksesor = simpul_dihapuskanan; // cari suksesor

while (suksesorkiri !- NULL) suksesor = suksesorkiri; // Putuskan suksesor dari pohon

if (suksesorindukkiri == suksesor ) {

suksesorindukkiri = suksesorkanan; suksesorkananinduk = suksesorinduk; }

else {

suksesorindukkanan = suksesorkanan; suksesorkananinduk = suksesorinduk; }

// Data pada suksesor disalin ke simpul yang dihapus simpul_dihapus = suksesor;

}

SimpulPohon *PohonBiner::cari(SimpulPohon *simpul, char data) {

if (simpul == NULL) return(NULL); else

if (data == simpuldata) return(simpul); else

if (data < simpuldata)

return(cari(simpulkiri, data)); else

Referensi

Dokumen terkait

Pergaulan bebas di antara muda-mudi, seperti yang terjadi sekarang ini seringkali membawa kepada hal-hal yang tidak di kehendaki, yakni terjadinya kehamilan

Bentuk penelitian yang digunakan adalah quasi experimental , karena dalam penelitian ini tidak mungkin sepenuhnya mengontrol variabel-variabel yang dapat

Gugus Pulau Bintan memiliki potensi wisata yang meliputi wisata alam, wisata budaya dan minat khusus yang tersebar di berbagai kecamatan yang terdapat pada Kabupaten Bintan

Media utama dalam perancangan ini adalah sebuah buku komik city guide pariwisata Surabaya sebagai media untuk mengenalkan dan mempromosikan pariwisata kota

Dari hasil penelitian selama 3 Bulan yang didapat menunjukan bahwa proyek mengalami keterlambatan dari segi waktu, namun dari segi biaya proyek yang dikeluarkan

Crash program merupakan cara melakukan percepatan dengan perkiraan biaya yang dibutuhkan untuk mereduksi waktu pekerjaan pada lintasan kritis.Perhitungan dimulai

 Terjadi kegagalan dalam memulihkan perfusi organ pada resusitasi cairan menandakan perdarahan masih berlanjut atau syok neurogenik Sudah resusitasi tp tidak ada perubahan. 