Slide Diktat C++ Hans D

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

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

Nested Class

34

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 *this;

}

50

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

// ...

};

53

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

62

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

}

65

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

97

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

karakterwhite space seperti:newline, tab, form feed, dsb.

103