You are on page 1of 103

Latar Belakang C++

Diciptakan oleh Bjarne Stroustrup di AT&T Bell Laboratories pada awal 1980an Pada mulanya dikenal sebagai C with Classes (nama C++ digunakan sejak 1983, setelah diusulkan oleh Rick Mascitti). 1985: disebarluaskan oleh AT&T, perangkat lunak cfront (C++ translator). Didasarkan pada bahasa C, Simula67, Algol68, Ada.

Simula67: konsep kelas. Algol68: konsep operator overloading dan kemungkinan penempatan deklarasi di manapun Ada: konsep template dan exception
1

Perbandingan C++ dengan C


Komentar di dalam C++ dapat dituliskan di antara // dan karakter newline Variable/objek dapat dideklarasikan / didenisikan di antara instruksi Typecasting dalam C++ dapat dipandang sebagai fungsi Function name overloading: fungsi dengan nama yang sama namun dengan signature yang berbeda. Nilai default pada parameter formal Template function, operator function, inline function. Reference variable, dan call by reference (berbeda dengan address of) Operator baru seperti global scope (unary ::), class scope (binary ::), new, delete, member pointer selectors (->*, .*) dan kata
2

kunci baru seperti: class, private, operator, dsb.


Nama kelas atau enumerasi (tag name) adalah nama tipe (baru) Anonymous union

Kompatibilitas antara C++ dan C


Program C yang dikompilasi oleh C++ tidak dapat menggunakan kata kunci dari C++ sebagai nama identier Setiap fungsi harus dideklarasikan (harus memiliki prototype) Fungsi yang bukan bertipe void, harus memiliki instruksi return Penanganan inisialisasi array karakter:

char ch[3] = "C++"; char ch[] = "C++";

/* C: OK, C++: error */ /* OK untuk C dan C++ */

Class
Untuk menciptakan tipe data baru. Tipe = kumpulan representasi bit + kumpulan operasi terhadap tipe tersebut Kelas menyediakan sekumpulan operasi (biasanya public) dan sekumpulan data bit (biasanya non-public) Peran: perancang kelas dan pengguna kelas.

Perancang: menentukan representasi internal objek serta operasi yang disajikan pada pengguna kelas. Pengguna: memanfaatkan operasi tersebut untuk memanipulasi objek

class vs. struct


Struct Memiliki 1 eld, masingmasing berupa data Setiap eld dapat diacu secara bebas dari luar Class Memiliki 1 member, masingmasing berupa data atau fungsi Pengaksesan member dari luar dapat dikendalikan (kata kunci private, public, dan protected

Ada dua jenis member:


Data member, yang merupakan representasi internal dari kelas Function member, kumpulan operasi (service/method) yang dapat diterapkan terhadap objek, seringkali disebut juga sebagai class interface
6

class vs. struct


struct typedef struct { int x; int y; } Point; void MoveTo (Point&) { // ... } class class Point { int x; int y; void MoveTo () { // ... } };

Pengaturan akses terhadap anggota kelas: private, public, protected Perhatikan perubahan parameter aktual pada prosedur MoveTo

Wilayah deklarasi public private protected

Makna dapat diakses oleh fungsi luar kelas dengan menggunakan operator selektor (. atau ->) hanya dapat diakses oleh fungsi kelas tersebut

seperti private, namun dapat diakses oleh kelas turunan Fungsi luar: fungsi yang bukan anggota kelas tersebut

Pendenisian member function dapat dilakukan dengan dua cara:


Di dalam class body, otomatis menjadi inline function Di luar class body, nama fungsi harus didahului oleh class scope. Di dalam kelas hanya dituliskan prototipe fungsi
8

class Stack { public: // function member void Pop(int& ); // deklarasi (prototype) void Push (int); // deklarasi (prototype) /*--- pendefinisian di dalam class body ---*/ int isEmpty() { return topStack == 0; } private: // data member int topStack; /* posisi yang akan diisi berikutnya */ int *data; };

// pendefinisian member function Pop di luar // class body void Stack::Pop(int& item) { if (isEmpty()) printf ("Error: stack kosong"); else { topStack--; item = data [topStack]; } } void Stack::Push (int item) { // . . . data [topStack] = item; topStack++; // . . . }

10

Pointer implisit this


Setiap function member memiliki pointer ke objek this Untuk kelas X, secara implisit pointer ini dideklarasikan sebagai X* this Pengaksesan anggota kelas (fungsi/data) dapat dituliskan dengan menyertakan this->
void Stack::Push (int item) { // . . . this->data [this->topStack] = item; this->topStack++; // . . . }

Manfaat: Setiap objek memiliki anggota data terpisah, namun anggota fungsi bersama, this diperlukan untuk mengakses data
11

Objek dari Kelas


Contoh deklarasi objek:
Stack Stack Stack Stack myStack; OprStack [10]; * pts = new Stack; ns = myStack; // definition & initialization

Pengaksesan anggota public:


int x; myStack.Push (99); OprStack[2].Pop(x); pts->Push(x); if (myStack.isEmpty()) printf ("Stack masih kosong . . . ");
12

ctor, dtor, dan cctor


Constructor /destructor = fungsi anggota yang secara otomatis dipanggil pada saat penciptaan/ pemusnahan objek. Nama konstruktor (ctor) = nama-kelas, Nama destruktor (dtor) = nama-kelas Sebuah kelas memiliki

0 ctor dan

1 dtor

Copy constructor (cctor) = konstruktor yang menciptakan objek dengan cara menduplikasi objek lain yang sudah ada

Jika tidak dideklarasikan oleh perancang kelas, cctor akan dilakukan secara bitwise copy
Untuk menciptakan array dari objek, kelas objek tersebut harus memiliki default ctor.
13

Penulisan kode kelas


Kode untuk kelas terdiri dari 1. Interface / specication: deklarasi kelas dituliskan ke dalam le X.h. 2. Implementation / body : denisi dari fungsi-fungsi anggota dari kelas tersebut. dituliskan ke dalam le X.cc, X.cpp, X.cxx atau X.C.
Untuk mencegah penyertaan header lebih dari satu kali, deklarasi kelas dituliskan di antara #ifdef XXXX_H dan #endif

14

// Nama file: Stack.h // Deskripsi: interface dari kelas Stack #ifndef STACK_H #define STACK_H class Stack { // // anggota data dan fungsi dari kelas Stack // }; #endif STACK_H

PERHATIAN: Di dalam header le, jangan menuliskan denisi objek/variabel karena akan mengakibatkan kesalahan multiply dened name pada saat linking dilakukan.
15

// Nama file: Stack.cc // Deskripsi: implementasi/body dari kelas Stack #include "Stack.h" Stack::Stack () { // ... ctor } Stack::Stack () { // ... dtor } // dst.. dst..

16

Pemanfaatan Kelas
Perancang kelas:

1. Kompilasi le implementasi (*.cc) menjadi kode objek (*.o) 2. Berikan le header (*.h) dan le kode objek (*.o) kepada pemakai kelas (mungkin dalam bentuk library)
Pemakai kelas:

1. Sertakan le header di dalam program (main.cc) 2. Kompilasi program C++ menjadi kode objek (main.o) 3. Link main.o dengan kode objek yang diberikan perancang kelas

17

Penciptaan/Pemusnahan Objek
Beberapa jenis objek dalam program C++:
Automatic object: diciptakan melalui deklarasi objek di dalam blok eksekusi dan dimusnahkan pada saat blok tersebut selesai eksekusi Static object: diciptakan satu kali pada saat program dimulai dan dimusnahkan pada saat program selesai Free store object: diciptakan dengan operator new dan dimusnahkan dengan operator delete. Kedua operator dipanggil secara eksplisit oleh pemakai Member object: sebagai anggota dari kelas

18

#include <Stack.h> Stack s0; /* global (static) */ int reverse() { static Stack tstack; /* local static */ // kode untuk fungsi reverse() di sini }

main () { Stack s1; Stack s2 (20); Stack *ptr;


19

// automatic // automatic

ptr = new Stack(50); while (...) { Stack s3;

// free store object // automatic

s3 = Stack (5); // ctor Stack(5) is called /* dtor Stack(5) is called */ //... } /* dtor s3 is called */ delete ptr; /* dtor *ptr is called */ } /* dtor s2 is called */ /* dtor s1 is called */ /* dtor s0 is called */

Copy Constructor
Copy constructor (cctor) dipanggil pada saat penciptaan objek secara duplikasi:
Deklarasi variabel dengan inisialisasi Passing parameter aktual ke parameter formal secara pass by value Pemberian return value dari fungsi yang nilai kembaliannya bertipe kelas tersebut (bukan ptr/ref)

cctor untuk kelas X dideklarasikan sebagai X(const X&);

20

class Stack { public: Stack(); // Stack (int); // Stack (const Stack&); // Stack(); // //... };

constructor constructor dengan ukuran stack copy constructor destructor

Stack::Stack (const Stack& s) { size = s.size; topStack = s.topStack; data = new int [size]; // PERHATIKAN: member "data" // harus di alokasi ulang, // tidak disalin dari "s.data". int i; for (i=0; i<topStack; i++) data[i] = s.data[i]; }
21

#include <Stack.h> f (Stack _) { // ... } Stack ll; main() { Stack x; Stack y = x; f(x); }

// ctor // cctor // cctor dari "x" ke "_"

22

Ctor Initialization List


ctor dari member akan dipanggil (sesuai urutan deklarasi) sebelum ctor kelas.
#include <Stack.h> class Parser { public: Parser(int); // ... private: Stack sym_stack, op_stack; String s; };

Urutan pemanggilan: ctor Stack (2), ctor String, lalu ctor Parser. sym_stack akan diinisialisasi oleh constructor Stack::Stack().
23

Jika ctor yang diinginkan adalah Stack::Stack(int), maka ctor Parser::Parser() harus melakukan constructor initialization list

24

Parser::Parser(int x) : { // ... }
Initialization list dapat berisi

sym_stack (x), op_stack (x)

1 inisialisasi

Setiap inisialisasi mencantumkan nama data anggota (atau nama kelas) dengan parameter aktual untuk ctor kelas anggota

25

Const Member
Atribut const dapat diterapkan pada anggota data maupun anggota fungsi
Pada anggota data: nilai anggota data tersebut akan tetap sepanjang waktu hidup objeknya.

Pengisian nilai awal harus dilakukan pada saat objek tersebut diciptakan, yaitu melalui constructor initialization list (hanya untuk ANSI)
Pada anggota fungsi: fungsi tersebut tidak akan mengubah (status) objek yang memanggilnya.

Object yang ditandai sebagai const tidak boleh memanggil fungsi anggota yang tidak memiliki atribut const

26

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

class Stack { public: int isEmpty() const; private: const int size; }; int Stack::isEmpty () const { return topStack == 0; } Stack::Stack () : size (defaultStacksize) { }

27

Data Anggota Statik


1 2 3 4 5 6 7 8 class Stack { public: // ... fungsi lain private: static int n_stack; // static data member!! // ... data & fungsi lain };

Setiap objek dari kelas memiliki sendiri salinan anggota data non-statik Anggota data statik dipakai bersama oleh seluruh objek dari kelas tersebut
28

Inisialisasi anggota statik


Keberadaan anggota statik (fungsi/data) tidak bergantung pada keberadaan objek dari kelas harus dilakukan di luar deklarasi kelas dan di luar fungsi anggota.

Apa yang terjadi jika diinisialisasi di dalam ctor?


Dilakukan di dalam le implementasi (X.cc), bukan di dalam header le
// inisialisasi anggota data statik (file Stack.cc) int Stack::n_stack = 0; Stack::Stack () { /* dst... */ }

29

Fungsi Anggota Statik


Fungsi anggota yang mengakses hanya anggota yang statik dapat dideklarasikan static Di dalam le: Stack.h
1 2 3 4 5 6 7
class Stack { // ... public: static int NumStackObj (); private: static int n_stack; };

Di dalam le: Stack.cc


1 2 3 4
int Stack::NumStackObj() { // kode yang mengakses hanya data member statik return n_stack; }

30

Sifat Anggota Statik


Anggota fungsi statik dapat dipanggil tanpa melalui objek dari kelas tersebut, misalnya:

if (Stack::NumStackObj() > 0) { printf ("....."); }


Anggota fungsi statik tidak memiliki pointer implisit this Data member yang statik diinisialisasi tanpa perlu adanya objek dari kelas tersebut

31

Friend
Friend = pemberian hak pada fungsi / kelas untuk mengakses anggota non-public suatu kelas.
1 2 3 4 class B { // kelas "pemberi ijin" friend class A; friend void F (int, char *); };

Friend bersifat satu arah Seluruh fungsi anggota kelas A dan fungsi F dapat mengakses anggota non-public dari kelas B

Kriteria penggunaan friend:


Hindari penggunaan friend, kecuali untuk fungsi operator Fungsi friend merupakan fungsi di luar kelas sehingga objek
32

parameter aktual mungkin dilewatkan secara call-by-value. Akibatnya operasi yang dilakukan terhadap objek bukanlah objek semula.

33

Nested Class

34

Operator Overloading
int a, b, c; float x, y, z; c = a + b; z = x + y; /* "fungsi +" di-overload */

Dengan fungsi tambah():


c = tambah (a, b); z = tambah (x, y);

Prototipe dua fungsi tambah:


int tambah (int, int); float tambah (float, float);

35

Fungsi operator
Fungsi operator = fungsi namanya adalah operator @ (@ diganti dengan simbol operator yang ada. Dapat dimanfaatkan dalam pemanipulasian objek dengan menggunakan simbol
Matrix A, B, C; C = A * B; /* perkalian matrix */ Complex x, y, z; x = y / z; /* pembagian bilangan kompleks */ Process p; p << SIGHUP; /* pengiriman sinyal dalam Unix */

Harus didenisikan oleh perancang kelas sebagai fungsi public


36

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

class Matrix { public: // fungsi-fungsi operator friend Matrix& operator* (const Matrix&, const Matrix&); }; class Complex { // ... public: Complex& operator/ (const Complex&); }; class Process { // ... public: void operator<< (int); };
37

Pendeklarasian Fungsi operator


Dua cara / bentuk:
Sebagai non-anggota

Jika mengakses anggota yang non-public maka fungsi tersebut harus dideklarasikan sebagai friend Jumlah parameter formal = jumlah operand
Sebagai anggota

Dideklarasikan pada wilayah public Parameter pertama dari operasi harus bertipe kelas tersebut Jumlah parameter formal = jumlah operand 1

38

Implementasi Sebagai Anggota


Deklarasi operator<< dan operator>>
1 2 3 4 5 6 7
class Stack { // public: void operator<< (int); void operator>> (int&); // ... };

// untuk push // untuk pop

Denisi fungsi operator


1 2 3 4 5 6 7
void Stack::operator<<(int item) { Push (item); } void Stack::operator>>(int& item) { Pop (item); }
39

Pemanggilan fungsi operator


Perbandingan nama operator X dengan nama-biasa void operator<< (int) void Push (int) void operator>> (int&)void Pop (int&) Sebagai fungsi anggota, fungsi operator dapat dipanggil dengan dua cara: dengan kata kunci operator atau hanya simbol
Stack s, t; s.Push (100); t.operator<< (500); t << 500;

40

Implementasi sebagai non-anggota


1 2 3 4 5 6 7 8 9 10 11 12 class Stack { friend void operator<< (Stack&, int); friend void operator>> (Stack&, int&); }; void operator<< (Stack& s, int v) { s.Push (v); } void operator>> (Stack& s, int& v) { s.Pop (v); }

41

Fungsi operator non-anggota


Dapat dimanfaatkan hanya sebagai simbol << atau >>, tidak sebagai fungsi dengan nama operator<< atau operator>>.
Stack s; s.operator<< (500); s << 500; // OK // ERROR

Error terdeteksi pada saat kompilasi karena kelas Stack tidak memiliki fungsi operator<<.

42

Fungsi anggota atau non-anggota


1. Implementasi sebagai anggota: ruas kiri operator harus berupa objek kelas tersebut 2. Jika ruas kiri operator bukan bertipe kelas tersebut, operator harus diimplementasikan sebagai non-anggota 3. Operator biner yang ingin dibuat komutatif yang salah satu operand bukan berasal dari kelas tersebut harus diimplementasikan sebagai dua fungsi dengan nama yang sama (overloading).

43

1 2 3 4 5 6 7 8 9 10 11 12 13 14

class Stack { // dalam contoh ini friend tidak diperlukan friend void operator+ (Stack&, int); friend void operator+ (int, Stack&); //... }; void operator+ (Stack& s, int m) { s.Push (m); } void operator+ (int m, Stack& s) { s.Push (m); }

44

Anggota atau non-anggota?


Operator assignment (=), subscript ([]), pemanggilan (()), dan selektor (->) harus diimplementasikan sebagai fungsi anggota Operator yang (dalam tipe standard) memerlukan operand lvalue seperti assignment dan arithmetic assignment (=, +=, ++, *=, dst) sebaiknya diimplementasikan sebagai member function Operator yang (dalam tipe standard) tidak memerlukan lvalue (+, -, &&, dst) operand sebaiknya diimplementasikan sebagai friend function

45

Beberapa manfaat fungsi operator: 1. Operasi aritmatika terhadap objek-objek matematik lebih terlihat alami dan mudah dipahami oleh pembaca program. c = a*b + c/d + e; // lebih mudah dimengerti c = tambah (tambah (kali (a,b), bagi(c,d)), e); 2. Dapat menciptakan operasi input/output yang seragam dengan memanfaatkan stream I/O dari C++. 3. Pengalokasian dinamik dapat dikendalikan perancang kelas melalui fungsi operator new dan delete. 4. Batas index pengaksesan array dapat dikendalikan lewat operator [].

46

Perancangan operator overloading


Assignment (=) dan address of (&) secara otomatis didenisikan untuk setiap kelas Pilihlah simbol operator yang memiliki makna yang paling mendekati makna aslinya Overloading tidak dapat dilakukan terhadap: :: (scope), .* (member pointer selector), . (member selector), ?: (arithmetic if), dan sizeof(). Urutan presedensi operator tidak dapat diubah Sintaks (arity, banyaknya operand) dari operator tidak dapat diubah Operator baru tidak dapat diciptakan Operator ++ dan tidak dapat dibedakan antara postx dan inx
47

Fungsi operator harus merupakan member atau paling sedikit salah satu argumen berasal dari kelas yang dioperasikan

48

Operator =
Assignment copy constructor

Pada assignment a = b, objek a dan b sudah tercipta sebelumnya Pada copy constructor Stack s = t;, hanya (t) yang sudah tercipta, objek s sedang dalam proses penciptaan.
Stack& Stack::operator= (const Stack& s) { /* assign stack "s" ke stack "*this" */ int i;

delete [] data; // bebaskan memory yang digunakan sebelumnya size = s.size; data = new int [size]; // alokasikan ulang topStack = s.topStack; for (i=0; i<topStack; i++) data [i] = s.data[i];
49

return *this; }

50

Return value dari operator=()


Perintah assignment berantai sbb:

int a, b, c; a = b = c = 4; // aksi eksekusi: a = (b = (c = 4));

Assignment berantai dapat diterapkan pada objek dari kelas, jika nilai kembali operator= = reference.

Fungsi anggota operator= harus memberikan nilai kembali berupa objek yang sudah mengalami operasi assignment (perintah return *this.)

51

Anggota kelas minimal


Perancang kelas wajib mendenisikan empat fungsi anggota berikut: 1. Constructor (default constructor maupun user-dened constructor), 2. Destructor, 3. Copy constructor, dan 4. Operasi assignment
class XC { public: XC (...); // constructor XC (const XC&); // copy constructor XC& operator= (const XC&); // assignment XC(); // destructor //... member public yang lain private:
52

// ... };

53

Operator[]
Dapat digunakan untuk melakukan subscripting terhadap objek. Jika digunakan sebagai subscripting batas index dapat diperiksa Parameter kedua (index/subscript) dapat berasal dari tipe data apapun: integer, oat, character, string, maupun tipe/kelas yang didenisikan user.

54

Template Function
Kebutuhan: operasi yang sejenis terhadap tipe yang berbeda-beda.
int min(int a, int b) { return a < b ? a : b; } float min(float a, float b) { return a < b ? a : b; } // dst...

55

Substitusi Makro
Trick yang biasa digunakan adalah dengan denisi makro
#define mmin(a,b) ((a) < (b) ? (a) : (b)) Contoh pemanfaatan: if (mmin (x++, y) == 0) printf ("...."); hasil ekspansi makro: if (((x++) < (y) ? (x++) : (y)) == 0) printf ("....");

Substitusi makro

pemanggilan fungsi

56

Template dalam C++


C++ menyediakan fasilitas fungsi template.
template <class Tjenis> Tjenis min (Tjenis a, Tjenis b) { return a < b ? a : b; }

Template: deklarasi fungsi generik yang dapat diinstansiasi bergantung pada tipe yang diperlukan pemakai. Instansiasi dilakukan oleh kompilator pada saat mengetahui ada pemanggilan fungsi pada nama generik tersebut.

57

Contoh lain:
template <class Type> Type min_arr (const Type x[], int size) /* mencari minimum dari array */ { Type min_val; int i; min_val = x[0]; for (i=1; i<size; i++) { if (x[i] < min_val) min_val = x[i]; } return min_val; }

58

Penggunaan fungsi template:


Nama tipe (kelas) yang dicantumkan di antara < dan > dapat lebih dari satu. Setiap nama tipe harus didahului oleh kata kunci class atau typename.
template <class T1, T2> void ..... // SALAH

Nama tipe yang dicantumkan di antara < dan > harus tercantum sebagai function signature.
template <class T1, class T2, class T3> T1 myFunc (T2 a, T3 b) /* error: T1 bukan bagian dari signature */ { /* ... */ }

59

Denisi template function dapat disertai oleh denisi non-template


template <class Type> Type min_arr (const Type x[], int size) { // ... } Complex min_arr (const Complex x[], int size) { // instansiasi khusus untuk dari min_arr kelas Complex }

60

Class Template
Konsep template dapat diterapkan juga pada kelas untuk menghasilkan kelas generik Kelas Stack generik dapat diinstansiasi sebagai Stack of integer, Stack of double, Stack of character, Stack of Complex, Stack of Process, Stack of String, dsb. Penciptaan objek kelas generik kls-generik < tipe-instansiasi > objek ; Stack<int> a; Stack<double> b (30); Stack<Complex> c; // Stack of integer // Stack of double, kapasitas m // Stack of Complex

Stack<int>, Stack<double>, ... dapat dipandang sebagai nama tipe baru


61

62

Denisi fungsi anggota kelas generik


Harus dituliskan sebagai fungsi template dengan scope Stack<Type>::.
template <class Type> Stack<Type>::Stack () { size = defaultStackSize; topStack = 0; data = new TYPE [size]; } template <class Type> void Stack<Type>::Push (Type item) { if (!isFull()) { data [topStack] = item; topStack++; } else /* ... */; }
63

Penulisan Kode
Kelas non-generik:

Deklarasi / interface dituliskan di XXXX.h Denisi fungsi anggota / implementation dituliskan di XXXX.cc
Kelas generik: Deklarasi (interface) maupun denisi fungsi anggota (implementation) dituliskan di XXXX.h Nama kelas yang sudah instansiasi merupakan nama tipe baru Nama tipe instansiasi dapat juga digunakan di dalam kelas untuk mendeklarasikan objek bertipe generik.
template <class Type> void Stack<Type>::Reverse() { Stack<Type> stemp; // objek lokal yang generik // ...algoritma dari Reverse()...
64

65

Pewarisan & Penurunan Kelas


Konsep-konsep yang berkaitan erat OOP: objek, kelas, pewarisan (inheritance), polymorphism, dan dynamic binding. Pewarisan = merupakan ciri unik dari OOP. C++ tanpa inheritance = abstract data type programming (ADTP), bukan OOP Pewarisan : pendenisian dan pengimplementasian sebuah kelas berdasarkan kelas-kelas yang sudah ada (reuse)

66

Kelas A mewarisi kelas B:


A = kelas turunan (derived class/ subclass), dan B = kelas dasar (base class/superclass) Seluruh anggota (data & fungsi) B diwariskan ke A, kecuali ctor, dtor, cctor, dan operator= memiliki ctor, cctor, dtor, dan operator= sendiri. Kelas A akan memiliki dua bagian:

1. Bagian yang diturunkan dari B, dan 2. Bagian yang didenisikan sendiri (spesik terhadap A) 3. Fungsi di dalam kelas turunan dapat mengakses semua anggota (fungsi/data) di dalam bagian non-private.

67

Penurunan kelas dalam C++


class kelas-turunan :mode-pewarisan kelas-dasar // ... ; Mode-pewarisan: mempengaruhi tingkat pengaksesan setiap anggota (fungsi/data) kelas dasar jika diakses melalui fungsi di luar kelas dasar maupun di luar kelas turunan.

68

Perubahan tingkat pengaksesan akibat pewarisan: Tingkat-Akses di kelas dasar protected public private private private Mode-pewarisan protected protected protected public protected public

private: = sangat tertutup (hanya fungsi anggota kelas tersebut yang dapat mengakses, public: = sangat terbuka (fungsi manapun, di dalam atau di luar kelas dapat mengakses anggota dalam bagian ini), protected: setengah terbuka / setengah tertutup (hanya kelas turunan yang dapat mengakses anggota pada bagian ini).

69

Contoh Pewarisan
Growing Stack: Stack yang kapasitasnya dapat bertambah/berkurang secara otomatis Push(): jika Stack penuh perbesar kapasitas Pop(): jika kapasitas tak terpakai cukup besar perkecil kapasitas Kelas GStack dapat diwariskan dari kelas Stack dengan cara : 1. Mengubah perilaku Pop() dan Push() yang ada pada kelas Stack 2. Menambahkan anggota data yang digunakan untuk menyimpan faktor penambahan/penciutan kapasitas stack

70

// File GStack.h // Deklarasi kelas GStack #ifndef GSTACK_H #define GSTACK_H #include "Stack.h" class GStack : public Stack { public: // ctor, cctor, dtor, oper= (tidak dituliskan)
71

// redefinition of Push & Pop void Push (int); void Pop (int&); private: int gs_unit; // fungsi untuk mengubah kapasitas void Grow(); void Shrink(); }; #endif GSTACK_H

// File GStack.cc // Definisi fungsi-fungsi anggota kelas GStack #include <stdio.h> #include "GStack.h" void GStack::Push (int x) { if (isFull()) Grow(); Stack::Push(x); } void GStack::Pop (int& x) { Stack::Pop(x); if (size - topStack > gs_unit) Shrink(); }

72

Ctor, dtor, cctor, dan operator= Kelas Dasar


Komponen yang berasal dari kelas dasar dapat dianggap sebagai sub-objek dari kelas turunan Pada penciptaan objek kelas turunan kelas turunan, konstruktor kelas dasar akan diaktifkan sebelum konstruktor kelas turunan. Pada pemusnahan objek kelas turunan, destruktor kelas dasar dipanggil setelah destruktor kelas turunan.

73

Penanganan copy constructor


Ada tiga kasus: 1. Kelas turunan tidak memiliki cctor, kelas dasar memiliki 2. Kelas turunan memiliki cctor, kelas dasar tidak memiliki 3. Baik kelas turunan maupun kelas dasar memiliki cctor Kasus (1): cctor kelas dasar akan dipanggil, inisialisasi kelas turunan dilakukan secara bitwise copy Pada kasus (2) dan (3), cctor dari kelas dasar tidak dipanggil, inisialisasi kelas dasar menjadi tanggung jawab kelas turunan.

74

Penginisialisasian kelas dasar oleh kelas turunan melalui ctor atau cctor dilakukan melalui constructor initialization list
1 2 3 4 5 6 7 8 9 // File GStack.cc // Definisi fungsi-fungsi anggota kelas GStack #include <stdio.h> #include "GStack.h" GStack::GStack(const GStack& s) : Stack (s) { gs_unit = s.gs_unit; }

75

Assignment ditangani seperti inisialisasi.


Jika kelas turunan tidak mendenisikannya, operator= dari kelas dasar akan dipanggil (jika ada). Jika kelas turunan mendenisikan operator= maka operasi assignment dari kelas dasar menjadi tanggung jawab kelas turunan.
1 2 3 4 5 6 7 8 9 10 // File GStack.cc #include <stdio.h> #include "GStack.h" GStack& GStack::operator=(const GStack& s) { Stack::operator= (s); // oper= dari Stack gs_unit = s.gs_unit; return *this; }
76

Polymorphism
Objek-objek dari kelas turunan memiliki sifat sebagai kelas tersebut dan sekaligus kelas dasarnya.

polymorphism (poly = banyak, morph = bentuk).


reference (ref) dan pointer (ptr) dapat bersifat polimork. Dalam C++ ref/ptr dapat digunakan untuk dynamic binding

ref/ptr memiliki tipe statik dan tipe dinamik. Tipe statik = tipe objek pada saat deklarasikan Tipe dinamik = tipe objek yang berubah pada saat eksekusi, bergantung pada objek yang diacu

77

Dynamic Binding
Tipe dinamik dari digunakan pada saat eksekusi untuk memanggil fungsi anggota yang berasal dari kelas berbeda-beda melalui sebuah ref/ptr dari kelas dasar. Fungsi yang akan dipanggil secara dinamik, harus dideklarasikan sebagai virtual (dilakukan di kelas dasar). Dalam contoh GStack fungsi Push() dan Pop() akan dipanggil secara dinamik Kelas Stack harus mendeklarasikan sebagai fungsi virtual

78

1 2 3 4 5 6 7 8 9 10 11

// File: Stack.h class Stack { public: // ctor, cctor, dtor, & oper= public: // services virtual void Push (int); virtual void Pop (int&); };

// <=== penambahan "virt // <=== penambahan "virt

79

#include <GStack.h> // tipe memiliki tipe dinamik void FuncVal (Stack s) { s.Push (10); } // memiliki tipe dinamik void FuncPtr (Stack *t) { t->Push (10); } // memiliki tipe dinamik void FuncRef (Stack& u) { u.Push (10); } main() { GStack gs; FuncVal (gs); // Stack::Push() dipanggil FuncPtr (&gs); // GStack::Push() dipanggil FuncRef (gs); // GStack::Push() dipanggil }
80

Virtual Destructor
Stack* sp [MAX_ELEM]; // ... kode-kode lain for (i=0; i<MAX_ELEM; i++) delete sp[i]; // tipe elemen: Stack/ GStack !

Destruktor mana yang akan dipanggil delete sp[i];? Diperlukan virtual destructor
class Stack { public: // ctor, dtor, cctor //... virtual Stack(); // };
81

Di dalam kelas turunan (GStack), destruktor tidak perlu dideklarasikan virtual karena otomatis mengikuti jenis dtor kelas dasar.

82

Abstract Base Class (ABC)


Abstract Base Class = kelas dasar untuk objek abstrak.

Contoh: DataStore, Vehicle, Shape, dst.


Bagaimana implementasi Shape::Draw()?

Tidak dapat diimplementasikan di dalam kelas Shape, namun harus dideklarasikan. Dideklarasikan sebagai fungsi pure virtual.
ABC = kelas yang memiliki fungsi pure virtual

83

class DataStore { public: // ... virtual void Clear() = 0; // pure virtual // ... };

Tidak ada objek yang dapat dibuat dari kelas dasar abstrak Di dalam kelas non-abstrak (yang mewarisi kelas dasar abstrak) fungsi pure virtual harus diimplementasikan.

84

// File: Stack.h // Deskripsi: deklarasi kelas Stack yang diturunkan dari DataSt class Stack : public DataStore { public: // ... void Clear (); };

// File: Tree.h // Deskripsi: deklarasi kelas Tree yang diturunkan dari DataSto class Tree : public DataStore { public: // ... void Clear (); };

85

Exception
Penambahan kode khusus untuk menangani kesalahan dalam eksekusi program membuat program menjadi rumit
1 2 3 4 5 6 7 8 int LakukanAksi () { // ... if ( .... ) // periksa kondisi kesalahan return NILAI_KHUSUS; else return NILAI_FUNGSI; }

86

1 2 3 4 5 6 7 8 9

if (LakukanAksi () == NILAI_KHUSUS) { // ... jalankan instruksi untuk menangani kesalahan } else { // instruksi-1 // instruksi-2 // ... // instruksi-n }

87

Exception
Kesalahan dalam eksekusi program = exception Penanganan exception dalam C++: throw, catch dan try.

return = kembali dari fungsi dengan normal throw = kembali dari fungsi dengan abnormal (exception).
1 2 3 4 5 6 7 8 int LakukanAksi () { // ... if ( .... ) // periksa kondisi kesalahan throw "Ada kesalahan"; else return NILAI_FUNGSI; }

catch dituliskan setelah sebuah blok try, untuk menangkap


88

exception yang di-throw


1 2 3 4 5 6 7 8 9 10 11 12 try { LakukanAksi (); // instruksi-1 // instruksi-2 // ... // instruksi-n } catch (const char*) { // ... jalankan instruksi untuk menangani kesalahan } // eksekusi berlanjut pada bagian ini ...

89

Exception Handler
Perintah dalam blok catch = exception handler. Sebuah blok try dapat memiliki exception handler, masing-masing untuk menangani tipe exception yang berbeda. Tipe handler ditentukan signaturenya. Catch-All handler memiliki signature ....
try { // } catch // } catch // } instruksi... (StackErr&) { handler untuk tipe "StackErr" (...) { handler untuk semua jenis exception lainnya

90

Pemilihan Handler
1. Jika terjadi exception hanya satu handler yang dipilih berdasarkan signature-nya 2. Instruksi di dalam handler yang terpilih dijalankan 3. Eksekusi dari blok try tidak dilanjutkan 4. Eksekusi berlanjut ke bagian yang dituliskan setelah bagian try-catch tersebut.

91

Contoh Kelas untuk Stack Exception


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
const int STACK_EMPTY = 0; const int STACK_FULL = 1; class StackExp { public: // ctor, cctor, dtor, oper= // services void DisplayMsg () const; static int NumException (); private: // static member, shared by all objects of this class static int num_ex; // pencacah jumlah exception static char* msg[]; // tabel pesan kesalahan const int msg_id; // nomor kesalahan };

92

Fungsi Anggota StackExp


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#include <stdio.h> #include "StackExp.h" #include <stream.h> int StackExp::num_ex = 0; char* StackExp::msg [] = { "Stack is empty!", "Stack is full!" }; StackExp::StackExp (int x) : msg_id (x) { num_ex++; // increase the exception counter } StackExp::StackExp (const StackExp& s) : msg_id (s.msg_id) { } void StackExp::DisplayMsg() const { cerr << msg[msg_id] << endl; } int StackExp::NumException () { return num_ex; }

93

Modikasi kelas Stack


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// file: Stack.cc // deskripsi: kelas Stack dengan exception handling #include "StackExp.h" void Stack::Push (int x) { if (isFull()) throw (StackExp (STACK_FULL)); else { /* algoritma Push() */ } } void Stack::Pop (int& x) { if (isEmpty()) throw (StackExp (STACK_EMPTY)); else { /* algoritma Pop() */ } }
94

// raise exception

// raise exceptio

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

#include "Stack.h" #include <stdio.h> main() { Stack s; int n; try { // ... s << 10; // ... } catch (StackExp& s) { s.DisplayMsg(); } n = StackExp::NumException(); if (n > 0) printf ("Muncul %s stack exception\n", n); }
95

C++ I/O Library


Pilihan: stdio.h atau stream.h?

stdio.h: stream.h:

stdin, stdout, stderr cin, cout, cerr

Mengapa stream?
1 2 3 4 5 6 7

template <class T> class Stack { public: // ... void Cetak() const; // ... };

96

97

Jenis elemen array data primitif / non-primitif? Untuk tipe Stack<Process>: cout << data[i] akan dilakukan melalui 1. anggota dari kelas cout stream::operator<< (const Process&); atau 2. fungsi non-anggota operator<< (stream&, const Process&); Salah satu dari fungsi tersebut harus didenisikan oleh perancang kelas Process. Alternatif 1 tidak mungkin dilakukan (mengubah deklarasi kelas stream)

98

Untuk memungkinkan cascading, nilai kembali fungsi harus bertipe stream&.


1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stream.h> class Process { // ... // overload oper<< untuk pencetakan kelas Process friend stream& operator<< (stream&, const Process&); // ... }; stream& operator<< (stream& s, const Process& p) { // pencetakan isi Process "p" ke stream "s" }

99

Keuntungan penggunaan kelas stream: 1. Type safety: tipe objek diketahui pada saat kompilasi 2. Extensible: fungsi operator<< dan operator>> pada kelas stream dapat di-overload untuk kelas baru 3. Mengurangi kesalahan pemakaian

100

I/O dengan kelas stream


Tiga kelas: 1. istream: stream input. Predened object: cin 2. ostream: stream output. (a) cout (b) cerr standard output standard error

3. iostream: stream dua arah (input/output) (diturunkan dari istream dan ostream) Manipulasi terhadap le disediakan kelas-kelas berikut: 1. ifstream yang diturunkan dari kelas istream 2. ofstream yang diturunkan dari kelas ostream 3. fstream yang diturunkan dari kelas iostream
101

Contoh
cout << objek/nilai-yang-dicetak; cin >> objek-yang-menerima-nilai; Pembacaan input dalam loop:
1 2 3 4 5 6 7 8 9 10 #include <stream.h> main () { char ch; while ( cin >> ch ) { // ... } } // FALSE jika mendapatkan EOF

Pembacaan karakter seperti yang ditunjukkan di atas akan mengabaikan


102

karakter white space seperti: newline, tab, form feed, dsb.

103

You might also like