Slide Diktat C++ Hans D
Transcript of Slide Diktat C++ Hans D
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 lunakcfront (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 / didefinisikan di antara instruksi
� Typecasting dalam C++ dapat dipandang sebagai fungsi
� Function name overloading: fungsi dengan nama yang sama namundengansignature 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
3
Kompatibilitas antara C++ dan C
� Program C yang dikompilasi oleh C++ tidak dapat menggunakan
kata kunci dari C++ sebagai nama identifier
� Setiap fungsi harus dideklarasikan (harus memilikiprototype)
� Fungsi yang bukan bertipevoid, harus memiliki instruksireturn
� Penanganan inisialisasi array karakter:
char ch[3] = "C++"; /* C: OK, C++: error */
char ch[] = "C++"; /* OK untuk C dan C++ */
4
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
5
class vs. struct
Struct Class
Memiliki � 1 field, masing-
masing berupa data
Memiliki � 1 member, masing-
masing berupa data atau fungsi
Setiap field dapat diacu secara be-
bas dari luar
Pengaksesan member dari luar
dapat dikendalikan (kata kun-
ci 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 sebagaiclass
interface
6
class vs. struct
struct classtypedef struct {
int x;
int y;
} Point;
void MoveTo (Point&) {
// ...
}
class Point {
int x;
int y;
void MoveTo () {
// ...
}
};
� Pengaturan akses terhadap anggota kelas:private, public,
protected
� Perhatikan perubahan parameter aktual pada prosedurMoveTo
7
Wilayah deklarasi Makna
public dapat diakses oleh fungsi luar kelas dengan meng-
gunakan operator selektor (. atau->)
private hanya dapat diakses oleh fungsi kelas tersebut
protected sepertiprivate, namun dapat diakses oleh kelas
turunan“Fungsi luar”: fungsi yang bukan anggota kelas tersebut
Pendefinisianmember function dapat dilakukan dengan dua cara:
� Di dalam class body, otomatis menjadi inline function
� Di luar class body, nama fungsi harus didahului olehclass 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;
};
9
// 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� Setiapfunction member memiliki pointer ke objekthis
� Untuk kelasX, secara implisit pointer ini dideklarasikan sebagaiX* this
� Pengaksesan anggota kelas (fungsi/data) dapat dituliskan denganmenyertakanthis->
void Stack::Push (int item) {
// . . .
this->data [this->topStack] = item;
this->topStack++;
// . . .
}
� Manfaat: Setiap objek memiliki anggota data terpisah, namunanggota fungsi bersama,this diperlukan untuk mengakses data
11
Objek dari Kelas� Contoh deklarasi objek:
Stack myStack;
Stack OprStack [10];
Stack * pts = new Stack;
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
secarabitwise copy
� Untuk menciptakan array dari objek, kelas objek tersebut harus
memiliki default ctor.
13
Penulisan kode kelas
Kode untuk kelas terdiri dari
1. Interface / specification:deklarasi kelas
dituliskan ke dalam fileX.h.
2. Implementation / body :definisi dari fungsi-fungsi anggota dari
kelas tersebut.
dituliskan ke dalam fileX.cc, X.cpp, X.cxx atauX.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 file, jangan menuliskandefinisiobjek/variabel karena akan mengakibatkan kesalahan “multiply defined
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 file implementasi (*.cc) menjadi kode objek (*.o)
2. Berikan file header (*.h) dan file kode objek (*.o) kepada
pemakai kelas (mungkin dalam bentuklibrary)
� Pemakai kelas:
1. Sertakan file 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 operatornew dan dimusnahkan
dengan operatordelete. Kedua operator dipanggil secaraeksplisitoleh pemakai
� Member object: sebagai anggota dari kelas
18
#include<Stack.h>
Stacks0;/*global(static)*/
intreverse(){
staticStacktstack;/*localstatic*/
//kodeuntukfungsireverse()disini
} main(){
Stacks1;
//automatic
Stacks2(20);
//automatic
Stack*ptr;
ptr=newStack(50);
//freestoreobject
while(...){
Stacks3;
//automatic
s3=
Stack(5);//ctorStack(5)iscalled
/*dtorStack(5)iscalled*/
//...
}
/*dtors3iscalled*/
deleteptr;/*dtor*ptriscalled*/
} /*dtors2iscalled*/
/*dtors1iscalled*/
/*dtors0iscalled*/
19
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 kelasX dideklarasikan sebagai
X(const X&);
20
class Stack {
public:
Stack(); // constructor
Stack (int); // constructor dengan ukuran stack
Stack (const Stack&); // copy constructor
˜Stack(); // 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; // ctor
Stack y = x; // cctor
f(x); // 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: ctorStack (2�), ctorString, lalu ctorParser.
sym_stack akan diinisialisasi oleh constructorStack::Stack().
23
Jika ctor yang diinginkan adalahStack::Stack(int), maka ctor
Parser::Parser() harus melakukanconstructor initialization list
24
Parser::Parser(int x) : sym_stack (x), op_stack (x)
{
// ...
}
� Initialization list dapat berisi� 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 melaluiconstructor initialization list (hanya untuk
ANSI)
� Pada anggota fungsi: fungsi tersebut tidak akan mengubah (status)
objek yang memanggilnya.
Object yang ditandai sebagaiconst tidak boleh memanggil fungsi
anggota yang tidak memiliki atributconst
26
1 class Stack {
2 public:
3 int isEmpty() const;
4 private:
5 const int size;
6 };
7
8 int Stack::isEmpty () const
9 {
10 return topStack == 0;
11 }
12
13 Stack::Stack () : size (defaultStacksize)
14 {
15 }
27
Data Anggota Statik
1 class Stack {
2 public:
3 // ... fungsi lain
4
5 private:
6 static int n_stack; // static data member!!
7 // ... data & fungsi lain
8 };
� Setiap objek dari kelas memiliki sendiri salinan anggota data
non-statik
� Anggota data statikdipakai bersamaoleh seluruh objek dari kelas
tersebut
28
Inisialisasi anggota statik� Keberadaan anggota statik (fungsi/data)tidak bergantung pada
keberadaan objek dari kelas
� harus dilakukandi luar deklarasi kelas dan di luar fungsi anggota.
Apa yang terjadi jika diinisialisasi di dalam ctor?
� Dilakukan di dalam file implementasi (X.cc),bukan di dalam header
file// inisialisasi anggota data statik (file Stack.cc)
int Stack::n_stack = 0;
Stack::Stack () {
/* dst... */
}
29
Fungsi Anggota Statik
Fungsi anggota yang mengakseshanyaanggota yang statik dapatdideklarasikanstatic Di dalam file: Stack.h
1 class Stack {
2 // ...
3 public:
4 static int NumStackObj ();
5 private:
6 static int n_stack;
7 };
Di dalam file: Stack.cc
1 int Stack::NumStackObj() {
2 // kode yang mengakses hanya data member statik
3 return n_stack;
4 }
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 implisitthis
� Data member yang statik diinisialisasi tanpa perlu adanya objek dari
kelas tersebut
31
Friend
Friend = pemberian hak pada fungsi / kelas untuk mengakses anggotanon-public suatu kelas.
1 class B { // kelas "pemberi ijin"
2 friend class A;
3 friend void F (int, char *);
4 };
� Friend bersifat satu arah
� Seluruh fungsi anggota kelasA dan fungsiF dapat mengaksesanggota non-public dari kelasB
Kriteria penggunaan friend:
� Hindari penggunaan friend, kecuali untuk fungsioperator
� Fungsifriend merupakan fungsidi luar kelas sehingga objek
32
parameter aktual mungkin dilewatkan secaracall-by-value.
Akibatnya operasi yang dilakukan terhadap objek bukanlah objek
semula.
33
Operator Overloading
int a, b, c;
float x, y, z;
c = a + b; /* "fungsi +" di-overload */
z = x + y;
Dengan fungsitambah():
c = tambah (a, b);
z = tambah (x, y);
Prototipedua fungsitambah:
int tambah (int, int);
float tambah (float, float);
35
Fungsioperator� Fungsi operator = fungsi namanya adalah “operator @” (@
diganti dengan simbol operator yang ada.
� Dapat dimanfaatkan dalam pemanipulasian objek denganmenggunakan 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 didefinisikan oleh perancang kelas sebagai fungsipublic
36
1 class Matrix {
2 public:
3 // fungsi-fungsi operator
4 friend Matrix& operator* (const Matrix&, const Matrix&);
5 };
6
7 class Complex {
8 // ...
9 public:
10 Complex& operator/ (const Complex&);
11 };
12
13 class Process {
14 // ...
15 public:
16 void operator<< (int);
17 };
37
Pendeklarasian Fungsioperator
Dua cara / bentuk:
� Sebagai non-anggota
– Jika mengakses anggota yangnon-public maka fungsi
tersebut harus dideklarasikan sebagaifriend
– Jumlah parameter formal = jumlah operand
� Sebagai anggota
– Dideklarasikan pada wilayahpublic
– Parameter pertama dari operasi harus bertipe kelas tersebut
– Jumlah parameter formal = jumlah operand� 1
38
Implementasi Sebagai Anggota
Deklarasioperator<< danoperator>>
1 class Stack {
2 //
3 public:
4 void operator<< (int); // untuk push
5 void operator>> (int&); // untuk pop
6 // ...
7 };
Definisi fungsi operator
1 void Stack::operator<<(int item) {
2 Push (item);
3 }
45 void Stack::operator>>(int& item) {
6 Pop (item);
7 }
39
Pemanggilan fungsioperator
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 kuncioperator atau hanya simbol
Stack s, t;
s.Push (100);
t.operator<< (500);
t << 500;
40
Implementasi sebagai non-anggota
1 class Stack {
2 friend void operator<< (Stack&, int);
3 friend void operator>> (Stack&, int&);
4 };
5
6 void operator<< (Stack& s, int v) {
7 s.Push (v);
8 }
9
10 void operator>> (Stack& s, int& v) {
11 s.Pop (v);
12 }
41
Fungsi operator non-anggota
Dapat dimanfaatkanhanyasebagai simbol<< atau>>, tidak sebagai
fungsi dengan namaoperator<< atauoperator>>.
Stack s;
s.operator<< (500); // ERROR
s << 500; // OK
Error terdeteksi pada saat kompilasi karena kelasStack tidak memiliki
fungsioperator<<.
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 class Stack {
2 // dalam contoh ini friend tidak diperlukan
3 friend void operator+ (Stack&, int);
4 friend void operator+ (int, Stack&);
5 //...
6 };
7
8 void operator+ (Stack& s, int m) {
9 s.Push (m);
10 }
11
12 void operator+ (int m, Stack& s) {
13 s.Push (m);
14 }
44
Anggota atau non-anggota?
� Operatorassignment (“=”), subscript (“[]”), pemanggilan (“()”),
dan selektor (“->”) harus diimplementasikan sebagai fungsi anggota
� Operator yang (dalam tipe standard) memerlukan operand lvalue
sepertiassignment danarithmetic 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
memanfaatkanstream I/O dari C++.
3. Pengalokasian dinamik dapat dikendalikan perancang kelas melalui
fungsi operatornew dandelete.
4. Batas index pengaksesan array dapat dikendalikan lewat operator[].
46
Perancanganoperator overloading� Assignment (‘=’) dan address of (‘&’) secara otomatis didefinisikan
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),
dansizeof().
� 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 postfix dan infix
47
� Fungsi operator harus merupakan member atau paling sedikit salah
satu argumen berasal dari kelas yang dioperasikan
48
Operator =
Assignment �� copy constructor
� Padaassignment a = b, objeka danb sudah tercipta sebelumnya
� Padacopy constructor Stack s = t;, hanya (t) yangsudahtercipta, objeks 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 value dari operator=()� Perintahassignment 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
kembalioperator= = reference.
Fungsi anggotaoperator= harus memberikan nilai kembali
berupa objek yangsudahmengalami operasi assignment
(perintahreturn *this.)
51
Anggota kelas minimal
Perancang kelas “wajib” mendefinisikanempat fungsi anggota berikut:
1. Constructor (default constructor maupunuser-defined constructor),
2. Destructor,
3. Copy constructor, dan
4. Operasiassignment
class XC {
public:
XC (...); // constructor
XC (const XC&); // copy constructor
XC& operator= (const XC&); // assignment
˜XC(); // destructor
//... member public yang lain
private:
52
Operator[]
� Dapat digunakan untuk melakukan subscripting terhadap objek.
� Jika digunakan sebagaisubscripting batas index dapat diperiksa
� Parameter kedua (index/subscript) dapat berasal dari tipe data
apapun: integer, float, character, string, maupun tipe/kelas yang
didefinisikan 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 definisi 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 kunciclassatautypename.
template <class T1, T2> // SALAH
void .....
� Nama tipe yang dicantumkan di antara ‘<’ dan ‘>’ harus tercantumsebagaifunction signature.
template <class T1, class T2, class T3>
T1 myFunc (T2 a, T3 b)
/* error: T1 bukan bagian dari signature */
{
/* ... */
}
59
� Definisi template function dapat disertai oleh definisi ”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 menghasilkankelas generik
KelasStack generik dapat diinstansiasi sebagai Stack of integer, Stackof double, Stack of character, Stack of Complex, Stack of Process, Stackof String, dsb.
Penciptaan objek kelas generik
kls-generik < tipe-instansiasi > objek ;
Stack<int> a; // Stack of integer
Stack<double> b (30); // Stack of double, kapasitas m
Stack<Complex> c; // Stack of Complex
Stack<int>, Stack<double>, ... dapat dipandang sebagai namatipe baru
61
Definisi fungsi anggota kelas generik
Harus dituliskan sebagai fungsitemplate denganscopeStack<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 diXXXX.h
– Definisi fungsi anggota / implementation dituliskan diXXXX.cc
� Kelas generik: Deklarasi (interface)maupun definisi fungsi anggota(implementation) dituliskan diXXXX.h
� Nama kelas yang sudah instansiasi merupakan nama tipe baru
� Nama tipe instansiasi dapat juga digunakan di dalam kelas untukmendeklarasikan objek bertipe generik.
template <class Type>
void Stack<Type>::Reverse() {
Stack<Type> stemp; // objek lokal yang generik
// ...algoritma dari Reverse()...
64
Pewarisan & Penurunan Kelas
Konsep-konsep yang berkaitan erat OOP: objek, kelas, pewarisan
(inheritance), polymorphism, dandynamic binding.
Pewarisan = merupakan ciri unik dari OOP.
C++ tanpa inheritance =abstract data type programming (ADTP), bukan
OOP
Pewarisan : pendefinisian 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, danoperator= memiliki ctor, cctor, dtor, dan
operator= sendiri.
� Kelas A akan memiliki dua bagian:
1. Bagian yang diturunkan dari B, dan
2. Bagian yang didefinisikan sendiri (spesifik 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 fungsidi luar kelas dasar
maupun di luar kelas turunan.
68
Perubahan tingkat pengaksesan akibat pewarisan:
Tingkat-Akses Mode-pewarisan
di kelas dasar private protected public
protected private protected protected
public private 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
KelasGStack dapat diwariskan dari kelasStack dengan cara :
1. Mengubah perilakuPop() danPush() yang ada pada kelas
Stack
2. Menambahkan anggota data yang digunakan untuk menyimpan
faktor penambahan/penciutan kapasitas stack
70
//FileGStack.h
//DeklarasikelasGStack
#ifndefGSTACK_H
#defineGSTACK_H
#include"Stack.h"
classGStack:publicStack{
public:
//ctor,cctor,dtor,oper=(tidakdituliskan)
//redefinitionofPush&Pop
voidPush(int);
voidPop(int&);
private:
intgs_unit;
//fungsiuntukmengubahkapasitas
voidGrow();
voidShrink();
};
#endifGSTACK_H
71
// 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 diaktifkansebelumkonstruktor kelas turunan.
� Pada pemusnahan objek kelas turunan, destruktor kelas dasar
dipanggilsetelahdestruktor kelas turunan.
73
Penanganancopy 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 secarabitwise copy
Pada kasus (2) dan (3), cctor dari kelas dasartidak dipanggil , inisialisasi
kelas dasar menjadi tanggung jawab kelas turunan.
74
Penginisialisasian kelas dasar oleh kelas turunan melalui ctor atau cctor
dilakukan melaluiconstructor initialization list
1 // File GStack.cc
2 // Definisi fungsi-fungsi anggota kelas GStack
3
4 #include <stdio.h>
5 #include "GStack.h"
6
7 GStack::GStack(const GStack& s) : Stack (s) {
8 gs_unit = s.gs_unit;
9 }
75
Assignment ditangani seperti inisialisasi.� Jika kelas turunantidak mendefinisikannya,operator= dari kelas
dasar akan dipanggil (jika ada).
� Jika kelas turunan mendefinisikanoperator= maka operasi
assignment dari kelas dasar menjadi tanggung jawab kelas turunan.
1 // File GStack.cc
2
3 #include <stdio.h>
4 #include "GStack.h"
5
6 GStack& GStack::operator=(const GStack& s) {
7 Stack::operator= (s); // oper= dari Stack
8 gs_unit = s.gs_unit;
9 return *this;
10 }
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 polimorfik.
� Dalam C++ ref/ptr dapat digunakan untukdynamic 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 darikelas dasar.
� Fungsi yang akan dipanggil secara dinamik, harus dideklarasikan
sebagaivirtual (dilakukan dikelas dasar).
� Dalam contohGStack fungsiPush() danPop() akan dipanggil
secara dinamik
KelasStack harus mendeklarasikan sebagai fungsi virtual
78
1 // File: Stack.h
2 class Stack {
3 public:
4 // ctor, cctor, dtor, & oper=
5
6 public:
7 // services
8 virtual void Push (int); // <=== penambahan "virt
9 virtual void Pop (int&); // <=== penambahan "virt
10
11 };
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 dipanggildelete sp[i];?
Diperlukanvirtual destructor
class Stack {
public:
// ctor, dtor, cctor
//...
virtual ˜Stack();
//
};
81
Di dalam kelas turunan (GStack), destruktortidak 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 implementasiShape::Draw()?
Tidak dapat diimplementasikan di dalam kelasShape, namun harus
dideklarasikan.
Dideklarasikan sebagai fungsipure virtual.
� ABC = kelas yang memiliki fungsipure 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 int LakukanAksi ()
2 {
3 // ...
4 if ( .... ) // periksa kondisi kesalahan
5 return NILAI_KHUSUS;
6 else
7 return NILAI_FUNGSI;
8 }
86
1 if (LakukanAksi () == NILAI_KHUSUS) {
2 // ... jalankan instruksi untuk menangani kesalahan
3 }
4 else {
5 // instruksi-1
6 // instruksi-2
7 // ...
8 // instruksi-n
9 }
87
Exception� Kesalahan dalam eksekusi program =exception
� Penangananexception dalam C++:throw, catch dantry.
return = kembali dari fungsi dengan normalthrow = kembali
dari fungsi dengan abnormal (exception).
1 int LakukanAksi ()
2 {
3 // ...
4 if ( .... ) // periksa kondisi kesalahan
5 throw "Ada kesalahan";
6 else
7 return NILAI_FUNGSI;
8 }
� catch dituliskan setelah sebuah bloktry, untuk menangkap
88
exception yang di-throw
1 try {
2 LakukanAksi ();
3 // instruksi-1
4 // instruksi-2
5 // ...
6 // instruksi-n
7 }
8 catch (const char*) {
9 // ... jalankan instruksi untuk menangani kesalahan
10 }
11
12 // eksekusi berlanjut pada bagian ini ...
89
Exception Handler� Perintah dalam blokcatch = exception handler.
� Sebuah bloktry dapat memiliki� � exception handler,masing-masing untuk menangani tipeexception yang berbeda.
� Tipe handler ditentukan “signature”nya. Catch-All handler memiliki“signature” “...”.
try {
// instruksi...
}
catch (StackErr&) {
// handler untuk tipe "StackErr"
}
catch (...) {
// handler untuk semua jenis exception lainnya
}
90
Pemilihan Handler
1. Jika terjadiexception hanya satuhandler yang dipilih berdasarkan
“signature”-nya
2. Instruksi di dalamhandler yang terpilih dijalankan
3. Eksekusi dari bloktry tidak dilanjutkan
4. Eksekusi berlanjut ke bagian yang dituliskan setelah bagian
try-catch tersebut.
91
Contoh Kelas untuk Stack Exception
1 const int STACK_EMPTY = 0;
2 const int STACK_FULL = 1;
34 class StackExp {
5 public:
6 // ctor, cctor, dtor, oper=
7 // services
8 void DisplayMsg () const;
9 static int NumException ();
1011 private:
12 // static member, shared by all objects of this class
13 static int num_ex; // pencacah jumlah exception
14 static char* msg[]; // tabel pesan kesalahan
15 const int msg_id; // nomor kesalahan
16 };
92
Fungsi AnggotaStackExp
1 #include <stdio.h>
2 #include "StackExp.h"
3 #include <stream.h>
45 int StackExp::num_ex = 0;
6 char* StackExp::msg [] = { "Stack is empty!", "Stack is full!" };
78 StackExp::StackExp (int x) : msg_id (x) {
9 num_ex++; // increase the exception counter
10 }
1112 StackExp::StackExp (const StackExp& s) : msg_id (s.msg_id) { }
1314 void StackExp::DisplayMsg() const {
15 cerr << msg[msg_id] << endl;
16 }
1718 int StackExp::NumException () {
19 return num_ex;
20 }
93
Modifikasi kelas Stack
1 // file: Stack.cc
2 // deskripsi: kelas Stack dengan exception handling
34 #include "StackExp.h"
56 void Stack::Push (int x) {
7 if (isFull()) throw (StackExp (STACK_FULL)); // raise exception
8 else {
9 /* algoritma Push() */
10 }
11 }
1213 void Stack::Pop (int& x) {
14 if (isEmpty()) throw (StackExp (STACK_EMPTY)); // raise exceptio
15 else {
16 /* algoritma Pop() */
17 }
18 }
94
1 #include "Stack.h"
2 #include <stdio.h>
34 main()
5 {
6 Stack s;
7 int n;
89 try {
10 // ...
11 s << 10;
12 // ...
13 }
14 catch (StackExp& s) {
15 s.DisplayMsg();
16 }
1718 n = StackExp::NumException();
19 if (n > 0)
20 printf ("Muncul %s stack exception\n", n);
21 }
95
C++ I/O Library� Pilihan:stdio.h ataustream.h?
– stdio.h: stdin, stdout, stderr
– stream.h: cin, cout, cerr
� Mengapastream?
1 template <class T>
2 class Stack {
3 public:
4 // ...
5 void Cetak() const;
6 // ...
7 };
96
Jenis elemen arraydata primitif / non-primitif?
Untuk tipeStack<Process>: cout << data[i] akan dilakukan
melalui
1. anggota dari kelascout
stream::operator<< (const Process&);
atau
2. fungsi non-anggota
operator<< (stream&, const Process&);
Salah satu dari fungsi tersebutharus didefinisikan olehperancang kelasProcess.
Alternatif 1 tidak mungkin dilakukan (mengubah deklarasi kelas
stream)
98
Untuk memungkinkancascading, nilai kembali fungsi harus bertipe
stream&.
1 #include <stream.h>
2
3 class Process {
4 // ...
5 // overload oper<< untuk pencetakan kelas Process
6 friend stream& operator<< (stream&, const Process&);
7 // ...
8 };
9
10 stream& operator<< (stream& s, const Process& p)
11 {
12 // pencetakan isi Process "p" ke stream "s"
13 }
99
Keuntungan penggunaan kelasstream:
1. Type safety: tipe objek diketahui pada saat kompilasi
2. Extensible: fungsioperator<< danoperator>> pada kelas
stream dapat di-overload untuk kelas baru
3. Mengurangi kesalahan pemakaian
100
I/O dengan kelasstream
Tiga kelas:
1. istream: stream input. Predefined object:cin
2. ostream: stream output.
(a) cout standard output
(b) cerr standard error
3. iostream: stream dua arah (input/output) (diturunkan dariistream danostream)
Manipulasi terhadap file disediakan kelas-kelas berikut:
1. ifstream yang diturunkan dari kelasistream
2. ofstream yang diturunkan dari kelasostream
3. fstream yang diturunkan dari kelasiostream
101
Contoh
cout << objek/nilai-yang-dicetak;
cin >> objek-yang-menerima-nilai;
Pembacaan input dalam loop:
1 #include <stream.h>
2
3 main ()
4 {
5 char ch;
6
7 while ( cin >> ch ) { // FALSE jika mendapatkan EOF
8 // ...
9 }
10 }
Pembacaan karakter seperti yang ditunjukkan di atas akan mengabaikan
102