BAB
3.
Kelas
dan Objek
3.1 Fungsi
Friend untuk Sebuah Kelas
Fungsi friend untuk sebuah
kelas memiliki akses terhadap semua anggota kelas baik private, terproteksi,
atau publik dan karakteristik ini membuat fungsi friend berguna pada banyak
aplikasi, khususnya pada pembebanan operator. Namun, akses bebas terhadap semua
anggota dari suatu kelas juga melanggar kapabilitas penyimpanan informasi dari
kelas. Karena pertemanan dijamin oleh kelas, oleh karena itu, deklarasi kelas
harus memuat deklarasi bahwa fungsi itu friend (teman) dari kelas itu. Selain
itu, fungsi friend bukanlah fungsi anggota dari kelas dimana di dalamnya ia
dideklarasikan sebagai friend. Jadi,
fungsi friend didefinisikan di luar tubuh kelas. Deklarasi atas prototipe
dari sebuah fungsi friend di dalam tubuh kelas diilustrasikan berikut.
Pendeklarasiannya diawali dengan katakunci friend
yang diikuti dengan tipe data dari fungsi dan pengenal (nama) fungsi yang
diikuti dengan suatu daftar tipe parameter fungsi yang diapit di dalam kurung
(). Kemudian pendeklarasian diakhiri dengan semikolon.
friend tipe
pengenal(tipe_parameter1, tipe_parameter2, …);
Sebagai contoh, sebuah fungsi dengan nama Luas() dideklarasikan sebagai sebuah fungsi friend dari kelas Rekt
yang merupakan sebuah kelas untuk bangun-bangun rektangular yang memiliki
sisi-sisi x dan y berikut.
friend int
Luas(const Rekt &b);
Pada deklarasi tersebut, data objek b dari kelas Rekt merupakan satu-satunya parameter fungsi. Definisi dari fungsi
friend diberikan di luar tubuh kelas. Fungsi tersebut didefinisikan sebagai
berikut.
int Luas(const
Rekt &b)
{return b.x * b.y ;}
Pada definisi tersebut, operator resolusi skop (::) tidak digunakan karena
fungsi Luas() bukanlah fungsi
anggota dari kelas.
Hal-hal berikut perlu diperhatikan terkait dengan fungsi friend untuk sebuah kelas.
- Jika sebuah fungsi F adalah fungsi friend untuk kelas B, maka F dapat mengakses semua anggotadari kelas B.
- Pertemanan dijamin oleh kelas. Oleh karena itu, fungsi friend harus dideklarasikan di dalam tubuh kelas seperti yang telah dijelaskan.
- Prototipe fungsi dari fungsi friend yang diawali dengan katakunci friend dideklarasikan di dalam tubuh kelas tetapi fungsi tersebut didefinisikan di luar tubuh kelas.
- Fungsi friend bukanlah fungsi anggota dari kelas yang menjadi temannya. Oleh karena itu, operator resolusi skop tidak diperlukan ketika mendefinisikan fungsi friend di luar tubuh kelas.
- Sebuah kelas dapat memiliki sebanyak mungkin fungsi friend. Dan sebuah fungsi friend dapat memiliki
- Sebuah fungsi friend dapat dideklarasikan di mana pun di dalam kelas. Penspesifikasi akses, yaitu public, protected, atau private, tidak memengaruhi fungsi friend.
Program berikut mengilustrasikan pendeklarasian dan pendefinisian suatu
fungsi friend.
Program 3.1 Mengilustrasikan
pendefinisian fungsi friend
|
|
|
#include <iostream>
using namespace std;
class Rekt{
friend
int Luas(const Rekt &a); //fungsi friend Luas()
int
x,y; // private secara default
public:
Rekt(int L, int W){x = L, y
= W;} //fungsi konstruktor
}; //akhir dari
kelas Rekt
int Luas (const Rekt &b) //definisi dari fungsi friend
{
return
b.x*b.y; //operator resolusi
skop tidak diperlukan
};
int main()
{
Rekt R1(5,6), R2(3,4) ; //deklarasi atas
dua objek R1 dan R2
cout<<"Luas Dari R1 =
"<<Luas(R1)<<"\n";
cout<<"Luas dari R2 =
"<<Luas(R2)<<"\n";
return
0 ;
}
|
KELUARAN
|
|
Luas Dari R1 =
30
Luas dari R2 =
12
|
Pada program tersebut, fungsi friend
mengambil semua argumen dari data objek kelas. Salah satu objek memiliki
dimensi 5 dan 6, fungsi friend
menghasilkan luas 30 sedangkan objek kedua R2 memiliki dimensi 3 dan 4 dan
luasnya dihasilkan sebesar 12. Keluaran program menunjukkan bahwa fungsi friend dapat mengakses anggota-anggota
data private dari kelas.
Sebuah kelas dapat mempunyai sebanyak mungkin fungsi friend. Pada program berikut, dua fungsi friend dideklarasikan untuk kelas Rekt. Fungsi friend
pertama menghitung luas, yang memerlukan data private dari objek. Fungsi friend kedua menghitung biaya perlakuan
terhadap permukaan luasan persegi-panjang.
Program 3.2 Mengilustrasikan sebuah
kelas yang memiliki lebih dari satu fungsi friend
|
|
|
#include <iostream>
using namespace std;
class Rekt{
friend
int Luas(const Rekt &a); //sebuah fungsi friend
int
x,y; //private secara default
public:
Rekt(int L, int W){x = L, y
= W;} //fungsi konstruktor
friend
double Biaya(const Rekt &a, double);
//fungsi friend kedua
}; //akhir dari
kelas Rekt
int Luas(const Rekt &b) //definisi dari fungsi Luas()
{
return
b.x*b.y;
}
double Biaya(const Rekt &b, double s) //definisi dari fungs Biaya()
{
return
b.x*b.y * s;
}
int main()
{
double
A = 4.5, B = 5.2; // A dan B untuk data
untuk fungsi Biaya()
Rekt R1(10,5), R2(20,5) ; // R1, R2 adalah dua objek
cout<<"Luas dari R1 =
"<<Luas(R1)<<"\n";
cout<<"Luas dari R2 =
"<<Luas(R2)<<"\n";
cout<<"Biaya =
"<<Biaya(R1,A)<<"\n";
cout<<"Biaya =
"<<Biaya(R2,B)<<"\n";
return
0 ;
}
|
KELUARAN
|
|
Luas dari R1 =
50
Luas dari R2 =
100
Biaya = 225
Biaya = 520
|
SATU FUNGSI FRIEND UNTUK BANYAK KELAS
Sebuah fungsi dapat menjadi friend
untuk banyak kelas. Ini diilustrasikan pada program berikut dimana di dalamnya
fungsi Tampil() dideklarasikan friend untuk dua kelas, yaitu kelas Persegi dan kelas Rekt.
Program 3.3 Mengilustrasikan sebuah fungsi
friend untuk lebih dari satu kelas
|
|
|
#include <iostream>
using namespace std;
class Persegi; //pra-deklearasi dari kelas
class Rekt { //kelas Rekt
int
x,y; //private secara default
public:
Rekt(int
A, int B) {x = A, y = B;}
int
Luas()
{return
x*y;}
friend
void Tampil(Rekt R, Persegi S);
//fungsi friend untuk Rekt
}; //akhir dari
kelas Rekt
class Persegi {
//kelas Persegi
int
sisi; //private secara default
public:
Persegi (int C){sisi = C;}
int
Luas ()
{return
sisi*sisi;}
friend
void Tampil(Rekt R, Persegi S);
//fungsi friend untuk Persegi
}; //akhir dari
kelas Persegi
void Tampil(Rekt R,
Persegi S) //definisi dari fungsi friend
{
cout<<"Luas dari Rektangular =
"<<R.Luas()<<endl;
cout<<"Luas dari Persegi =
"<<S.Luas()<< endl;
}
int main()
{
Rekt R1(10, 5);
Persegi S1(10);
Tampil(R1, S1);
return
0;
}
|
KELUARAN
|
|
Luas dari
Rektangular = 50
Luas dari
Persegi = 100
|
3.2 Kelas
Friend
Ketika semua atau hampir semua fungsi dari sebuah kelas memerlukan akses
terhadap anggota data dan fungsi anggota dari kelas lain, kelas tersebut secara
menyeluruh dapat dideklarasikan friend
untuk kelas lain itu. Sebagai contoh, jika fungsi-fungsi dari sebuah kelas A
memerlukan akses terhadap anggota-anggota publik, private, dan terproteksi dari
kelas B, maka kelas A dapat dideklarasikan sebagai friend class A; di dalam tubuh dari kelas B. Seperti Anda ketahui, friend adalah katakunci di dalam C++.
Deklarasi tersebut diilustrasikan berikut.
class B
{
friend class A; //deklarasi bahwa kelas A adalah friend dari kelas B
private:
statemen_statemen;
friend class C; // deklarasi bahwa kelas C adalah friend dari kelas B
public:
statemen_statemen_lain;
};
KARAKTERISTIK-KARAKTERISTIK DARI KELAS FRIEND
Karakteristik-karakteristik dari kelas friend berikut perlu diketahui.
- Jika kelas A merupakan friend untuk kelas B, maka fungsi-fungsi dari A dapat mengakses semuaanggota dari B.
- Jika kelas A merupakan friend untuk kelas B, maka hal itu tidak berarti bahwa B juga friend untuk kelas A. Pertemanan C++ tidak timbal balik atau resiprokal.
- Pertemanan dijamin oleh kelas yang anggota-anggotanya akan diakses. Jika kelas A adalah friend untuk kelas B, maka kelas A harus dideklarasikan di dalam definisi dari kelas B.
- Jika kelas A adalah friend untuk kelas B dan kelas B adalah friend untuk kelas C, maka hal itu tidak berarti bahwa kelas A juga friend untuk kelas C atau kelas B adalah friend untuk kelas A atau kelas C adalah friend untuk kelas B atau kelas A. Pertemanan dalam C++ tidak ditransmisikan dan tidak timbal-balik.
- Sebuah kelas dapat menjadi friend untuk lebih dari satu kelas. Dan sebuah kelas dapat memiliki lebih dari satu kelas friend.
Pada program berikut, Anda mendefinisikan sebuah kelas Kubik untuk komponen-komponen prismatis
dengan dasar rektangular. Kelas memiliki dua fungsi untuk menghitung volume dan
luas permukaan eksternal dari elemen-elemen kubikel. Kelas kedua dengan nama Lukis didefinisikan. Kelas ini
mempunyai sebuah fungsi untuk menghitung biaya pelukisan permukaan eksternal
dari objek-objek kelas Kubik. Kelas Lukis dideklarasikan sebagai friend untuk kelas Kubik.
Program 3.4 Mengilustrasikan deklarasi
sebuah kelas friend untuk suatu kelas
|
|
|
#include <iostream>
using namespace std;
class Kubik {
friend
class Lukis; //deklarasi dari
kelas friend
public:
void
sisi2(int , int, int);
int
Luas();
int
volume();
int
x, y, z;
}; //akhir dari
kelas Kubik
void Kubik::sisi2(int L, int W, int H)
{x = L, y = W,z
= H; } //pengaturan sisi-sisi dari Kubik
int Kubik::Luas() //definisi dari Luas()
{return 2*(x*y +y*z +z*x);}
int
Kubik::volume() //definisi dari
volume()
{return x*y*z ;}
class Lukis{
//deklarasi dari kelas friend Lukis
private:
int
R;
public:
Lukis() {R = 1;} //konstruktor default
Lukis(int S) {R = S;} //konstruktor parametris
Kubik
C; // C adalah objek dari kelas Kubik
int
Luas (){return C.Luas ();}
int
biaya(int R , Kubik C )
{return
R* C.Luas ();}
}; //akhir dari
kelas Lukis
int main()
{
Kubik C1 ; //C1
adalah objek dari kelas Kubik
C1.sisi2 (5,6,5 );
Lukis P1 ; //P1
adalah objek dari kelas Lukis
int k = 4;
cout<<"Volume dari C1 =
"<<C1.volume()<<"\n";
cout<<"Luas permukaan dari C1 =
"<<C1.Luas()<<"\n";
cout<<"Biaya pelukisan P1 =
"<<P1.biaya(k, C1)<<"\n";
return
0 ;
}
|
KELUARAN
|
|
Volume dari C1
= 150
Luas permukaan
dari C1 = 170
Biaya pelukisan
P1 = 680
|
3.3 Pointer
(Menunjuk) Ke Sebuah Kelas
Pointer ke sebuah kelas dapat dideklarasikan dengan cara yang sama dengan
apa dilakukan terhadap variabel integer atau double. Dimisalkan bahwa Anda
memiliki sebuah kelas dengan nama List
dan dimisalkan bahwa L1 adalah
sebuah objek dari kelas itu. Dimisalkan juga bahwa ptr adalah sebuah pointer yang menunjuk kelas List. Untuk deklarasi pointer ke List, Anda bisa menggunakan kode
berikut.
List L1; //deklarasi bahwa L1 adalah
objek dari List
List *ptr; //deklarasi pointer ke List
ptr = &(List) L1; //penugasan nilai kepada ptr
Baris terakhir dapat pula dituliskan dengan ptr = &List (L1);. Program berikut memberikan ilustrasi dari
pointer ke kelas.
Program 3.5 Mengilustrasikan definisi
dari pointer yang menunjuk ke sebuah kelas
|
|
|
#include <iostream>
using namespace std;
class List
{
private:
int
x,y; //x = jumlah item, y = harga
per tem
public:
void
Setdata(int a, int b) //fungsi publik untuk
mengakses x, y
{
cout<<"Masukkan jumlah
item: "; cin>>a;
cout<<"Masukkan harga per
item: "; cin>>b;
x = a, y = b;
}
void
Tampil1()
{cout<<"Jumlah item = "<<x<<endl;}
void
Tampil2()
{cout<<"Harga per item = "<<y<<endl;}
void
Tampil3()
{cout<<"Biaya dari
"<<x<<" buah item dengan harga "<<y<<" per item = "<<x*y<<endl;}
}; //akhir dari
kelas List
void main()
{
List L1;
List *ptr; //pointer
ke List
ptr = &(List) L1; //menugaskan alamat dari objek kelas
int
i,j;
(*ptr).Setdata(i,j); //nilai-nilai ditugaskan oleh user
ptr -> Tampil1(); // (*ptr) dan ptr-> ekivalen
ptr -> Tampil2();
(*ptr).Tampil3();
}
|
KELUARAN
|
|
Masukkan jumlah
item: 45
Masukkan harga
per item: 54
Jumlah item =
45
Harga per item
= 54
Biaya dari 45
buah item dengan harga 54 per item = 2430
|
Program tersebut juga menunjukkan bahwa untuk memanggil suatu fungsi kelas
di dalam main() melalui sebuah
pointer ptr, salah satu dari kedua
kode berikut dapat digunakan.
ptr -> Tampil3();
atau
(*ptr).Tampil3();
Kedua statemen tersebut ekivalen. Pada statemen kedua, *ptr harus ditempatkan di dalam kurung
karena operator dot (.) memiliki keutamaan yang lebih tinggi daripada operator
dereferensi (*). Program berikut mengilustrasikan bagaimana fungsi-fungsi
berelasi ke objek kedua dari kelas yang sama dapat dipanggil dengan menggunakan
operator inkremen (++) pada pointer kelas yang menunjuk ke objek pertama dari
kelas. Kedua objek harus dideklarasikan sebelum operator inkremen.
Program 3.6 Mengilustrasikan penginkremenan
pointer ke objek kelas pertama menghasilkan pointer ke objek kedua
|
|
|
#include <iostream>
using namespace std;
class List{
private:
int
x, y, z;
public:
void
Tampil1()
{cout<<"Selamat datang ke pasar ini"<<endl;}
void
set_harga(int a, int b, int c)
{x = a, y = b, z = c;}
void
Tampil2()
{
cout<<"Harga dari item1 =
"<<x<<endl;
cout<<"Harga dari item2 =
"<<y<<endl;
cout<<"Harga dari item3 =
"<<z<<endl;
}
}; //akhir dari
kelas List
void main()
{
List L1;
List *ptr; //pointer
ke List
ptr = &(List) L1; //penugasan alamat dari L1
kepada pointer
ptr -> set_harga(6, 8, 10); //fungsi yang berelasi dengan L1
ptr -> Tampil1();
cout<<"Daftar Harga
1"<<endl;
ptr ->Tampil2();
List L2; //L2
adalah objek kedua dari kelas
*ptr++; //penginkremenan
pointer ke L1 menghasilkan pointer ke L2.
ptr -> set_harga(32,27,38); //fungsi
yang berelasi dengan L2.
ptr -> Tampil1();
cout<<"Daftar Harga
2"<<endl;
ptr -> Tampil2();
}
|
KELUARAN
|
|
Selamat datang
ke pasar ini
Daftar Harga 1
Harga dari
item1 = 6
Harga dari
item2 = 8
Harga dari
item3 = 10
Selamat datang
ke pasar ini
Daftar Harga 2
Harga dari
item1 = 32
Harga dari
item2 = 27
Harga dari
item3 = 38
|
Pada program di atas, pointer ptr
dideklarasikan sebagai pointer yang menunjuk ke kelas List dengan L1 sebagai salah satu objeknya. Fungsi set_harga() dan Tampil() dipanggil. Terlihat bahwa pemanggilan kedua fungsi ini
adalah untuk objek L1. Kemudian
sebuah objek kedua L2 dideklarasikan
dan ptr diinkremen. Penginkremenan
menyebabkan ptr menunjuk ke objek kedua L2. Fungsi set_harga() dan Tampil()
dipanggil untuk L2 menggunakan
pointer tersebut.
3.4 Pointer
(Menunjuk) Ke Objek dari Sebuah Kelas
Dimisalkan bahwa L1 adalah
sebuah objek dari kelas List,
pointer yang menunjuk ke L1 dapat dideklarasikan dan ditugaskan sebagai
berikut.
List *ptr = &L1;
Program 3.7 Mengilustrasikan pendefinisian
pointer yang menunjuk ke sebuah objek kelas
|
|
|
#include <iostream>
using namespace std;
class List{
private:
int
x, y, z;
public:
List (int a, int b, int c) {x = a, y = b, z = c;}
//konstruktor
void Tampil()
{
cout<<"Harga dari item 1
= "<<x<<endl;
cout<<"Harga dari item 2
= "<<y<<endl;
cout<<"Harga dari item 3
= "<<z<<endl;
}
}; //akhir dari
kelas List
void main()
{
int
n = 0;
List L1 (12, 15, 27);
cout<<"List
"<<++n<<endl;
List *ptr = &L1; //(*ptr) dan ptr-> ekivalen
ptr -> Tampil();
cout<<"\nList"<< ++n
<<"\n";
List L2(30, 54, 60);
ptr = & L2 ;
(*ptr).Tampil();
}
|
KELUARAN
|
|
List 1
Harga dari item
1 = 12
Harga dari item
2 = 15
Harga dari item
3 = 27
List2
Harga dari item
1 = 30
Harga dari item
2 = 54
Harga dari item
3 = 60
|
3.5 Pointer
(Menunjuk) Ke Fungsi Anggota Kelas
Deklarasi dan penugasan pointer kepada fungsi anggota dari kelas
diilustrasikan berikut.
tipe (nama_kelas ::*nama_pointer)(tipe_parameter)
= &nama_kelas :: nama_fungsi;
Pada sintaksis tersebut, kata pertama tipe
menandakan tipe data dari nilai balik dari fungsi, yang diikuti dengan (dalam
kurung) pengenal kelas, operator resolusi skop dan operator indireksi (*) dan
pengenal pointer. Penugasan (sisi kanan dari =) operator alamat & yang
diikuti dengan nama kelas, operator resolusi skop, dan diakhiri dengan
semikolon atau titik-koma. Pada program 3.7 yang diberikan berikut, Anda
memiliki sebuah fungsi dengan nama set_sisi(),
sebuah fungsi publik dari kelas Rekt
untuk inisialisasi sisi-sisi dari persegi-panjang, yang didefinisikan berikut.
void
set_sisi(int L, int W ){x = L , y = W;}
Pointer *ptrSet yang menunjuk
ke fungsi ini dideklarasikan dan ditugaskan sebagai berikut.
void (Rekt:: *ptrSet)(int, int) = &Rekt :: set_sisi;
Untuk memanggil fungsi ini untuk sebuah objek R1 dengan panjang 20 dan lebar 15, Anda bisa menuliskan kode
berikut.
(R1.*ptrSet)(20, 15);
Program berikut mengilustrasikan penggunaan pointer yang menunjuk ke
sebuah fungsi anggota dari kelas.
Program 3.8 Mengilustrasikan pendefinisian
pointer yang menunjuk ke sebuah objek kelas
|
|
|
#include <iostream>
using namespace std;
class Rekt {
int
x, y; //private secara default
public:
void
set_sisi(int L, int W){x = L, y = W;}
int
Luas() //definisi dari fungsi Luas()
{
return
x*y;
}
}; //akhir dari
kelas Rekt
int main()
{
Rekt R1, R2, R3;
void
(Rekt:: *ptrSet)(int,int) = & Rekt :: set_sisi;
(R1.*ptrSet) (20,15);
cout<<"Luas dari R1 =
"<<R1.Luas()<<endl;
(R2.*ptrSet) (20,30); //objek R2 memanggil fungsi dengan pointer
cout<<"Luas dari R2 =
"<<R2.Luas()<<endl;
Rekt *ptr3 = &R3; // declaring pointer to object R3 of
class
(ptr3 ->*ptrSet)(16,10); //memanggil
fungsi dengan pointer yang menunjuk ke objek
cout<<"Luas dari R3 =
"<<R3.Luas()<<endl;
return
0 ;
}
|
KELUARAN
|
|
Luas dari R1 =
300
Luas dari R2 =
600
Luas dari R3 =
160
|
3.6 Pointer
(Menunjuk) Ke Anggota Data dari Kelas
Sintaksis untuk pendeklarasian dan penugasan pointer untuk menunjuk ke
anggota data adalah sebagai berikut
tipe
nama_kelas :: *nama_pointer = & nama_kelas :: nama_data;
Sebagai contoh, sebuah kelas dengan nama Rekt yang memiliki anggota-anggota data int x dan int y, pointer
ptrx dan ptry yang menunjuk ke anggota-anggota data dideklarasikan sebagai
berikut.
int Rekt ::
*ptrx = &Rekt :: x;
int Rekt ::
*ptry = &Rekt :: y;
Aplikasi diilustrasikan pada program berikut.
Program 3.9 Mengilustrasikan pendefinisian
pointer-pointer yang menunjuk ke anggota data dari kelas
|
|
|
#include <iostream>
using namespace std;
class Rekt{
friend
int Luas(Rekt a); //fungsi friend
int
x, y; //anggota-anggot data private secara default
public:
friend
double biaya(Rekt a, double); //fungsi friend lain
Rekt (int L, int W){x = L,y
= W;} //konstruktor
}; //akhir dari
kelas Rekt
int Luas (Rekt b)
//definisi dari fungsi Luas() menggunakan pointer
{
int
Rekt :: *ptrx = &Rekt :: x; //ptrx adalah pointer untuk x
int
Rekt :: *ptry = &Rekt :: y; //ptry adalah pointer untuk y
Rekt *ptrb = &b; //ptrb adalah pointer
yang menunjuk ke b
return
b.*ptrx * b.*ptry;
};
double biaya(Rekt b ,
double m)
{
return
b. x* b. y * m;
}
int main()
{
double
n = 4.5;
Rekt R1(5,6), R2(3,4);
cout<<"Luas of R1 =
"<<Luas(Rekt(R1))<<"\n";
cout<<"Luas of R2 =
"<<Luas(Rekt(R2))<<"\n";
cout<<"biaya for R1 =
"<<biaya(Rekt(R1),n)<<"\n";
return
0 ;
}
|
KELUARAN
|
|
Luas of R1 = 30
Luas of R2 = 12
biaya for R1 =
135
|
3.7 Mengakses
Data Private dari Objek Melalui Pointer
Data private dari sebuah objek dapat diakses melalui pointer jika terdapat
satu anggota publik. Ini memungkinkan karena anggota-anggota data publik dan anggota-anggota
data private dari suatu objek disimpan pada blok-blok memori sekuensial. Jika
Anda mengetahui alamat dari satu anggota data, maka Anda dapat menentukan nilai
dari anggota-anggota data lain dengan menginkremen atau mendekremen pointer.
Hal ini diilustrasikan pada program berikut. Pada program, Anda juga mencari
alamat dari data publik dan data private dengan mendapatkan nilai-nilai dari
pointer terdekremen. Namun, jika Anda mencoba menentukan alamat dari data
private secara langsung dengan menggunakan &L1.z pada program, maka
hasilnya akan berupa pesan error.
Program 3.10 Mengilustrasikan pengaksesan
data private dari sebuah objek menggunakan pointer
|
|
|
#include <iostream>
using namespace std;
class List{
private:
int
x, y, z;
public:
int
Alfa;
List
(int a, int b, int c) {x = a,
y = b, z = c;} //konstruktor
}; //akhir dari
kelas List
void main()
{
List L1(10, 20, 30);
int
*pAlfa; //pointer ke
suatu integer
L1. Alfa = 50;
pAlfa = & L1.Alfa; //penugasan nilai kepada pointer
cout<<"Alfa =
"<<*pAlfa<< endl;
cout<<"Alamat dari Alfa =
"<<pAlfa<< endl;
pAlfa--; //mendekremen
pointer untuk mendapatkan z
cout<<"Data z dari L1 =
"<<*pAlfa <<endl;
cout<<"Alamat dari z =
"<<pAlfa<<endl;
pAlfa--; //mendekremen
pointer untuk mendapatkan y
cout<<"Data y dari L1 =
"<<*pAlfa <<endl;
cout<<"Alamat dari y =
"<<pAlfa<<endl;
pAlfa--; //mendekremen
pointer untuk mendapatkan x
cout<<"Data x dari L1 =
"<<*pAlfa <<endl;
cout<<"Alamat dari x =
"<<pAlfa<<endl;
}
|
KELUARAN
|
|
Alfa = 50
Alamat dari
Alfa = 0018FF44
Data z dari L1
= 30
Alamat dari z =
0018FF40
Data y dari L1
= 20
Alamat dari y =
0018FF3C
Data x dari L1
= 10
Alamat dari x =
0018FF38
|
Pada program berikut, Anda akan mengawalinya dari alamat objek. Alamat
objek merupakan alamat dari data pertama pada objek.
Program 3.11 Mengilustrasikan pengaksesan
data private dari alamat objek
|
|
|
#include <iostream>
using namespace std;
class List{
private:
int
x, y, z;
public:
int
s;
List(int a, int b, int c) {x = a, y = b, z = c;}
//konstruktor
}; //akhir dari
kelas List
void main()
{
List L1( 10, 20 , 30); ;
L1.s = 40;
int
*ptrL1 ;
ptrL1 = (int*)& L1 ;
cout<<"Nilai dari x =
"<<*ptrL1<<endl;
cout<<"Alamat dari x =
"<<ptrL1<<endl;
ptrL1++;
cout<<"Data y dari L1 =
"<<*ptrL1<<endl;
cout<<"Alamat dari y =
"<<ptrL1<<endl;
ptrL1++;
cout<<"Data z dari L1 =
"<<*ptrL1<<endl;
cout<<"Alamat dari z =
"<<ptrL1<<endl;
ptrL1 ++;
cout<<"Data s dari L1 =
"<<*ptrL1<<endl;
cout<<"Alamat dari s =
"<<ptrL1<<endl;
}
|
KELUARAN
|
|
Nilai dari x =
10
Alamat dari x =
0018FF38
Data y dari L1
= 20
Alamat dari y =
0018FF3C
Data z dari L1
= 30
Alamat dari z =
0018FF40
Data s dari L1
= 40
Alamat dari s =
0018FF44
|
Nilai dari pointer ptrL1
merupakan alamat dari data pertama yang merupakan alamat dari x. Dengan
menginkremen pointer ini, Anda akan mendapatkan pointer yang menunjuk ke data
kedua, yaitu y. Dengan melakukan hal yang sama, Anda akan mendapatkan pointer
yang menunjuk ke data ketiga, yaitu z.
3.8 Pointer
this
Kata this merupakan katakunci
dalam C++ dan merupakan nama pointer yang menunjuk ke suatu objek kelas. Ketika
sebuah objek diciptakan, kompiler menciptakan pointer this yang menjejak alamat dari objek itu. Pointer this bukanlah bagian dari objek tetap
objek dapat mengaksesnya atau Anda dapat mengatakan bahwa sebuah objek dapat
mengakses alamatnya sendiri. Ketika objek memanggil sebuah fungsi anggota
kelas, pointer this menjadi argumen
implisit dari fungsi dan fungsi tersebut memproses data objek.
Pada program berikut, this dan *this digunakan pada konstruktor kelas.
Selain itu, Anda mencari nilai dari pointer this untuk dua objek C1 dan C2. Anda juga mencari alamat dari objek
C1 dan C2 menggunakan operator alamat &. Nilai pointer this untuk kedua objek sama dengan alamat-alamatnya.
Program 3.12 Mengilustrasikan aplikasi
dari pointer this
|
|
|
#include <iostream>
using namespace std;
class Kubik {
public:
Kubik(int L, int W, int H){this ->x=L, (*this).y=W,
this->z=H;}
//fungsi di atas adalah konstruktor
int
luas_permukaan();
int
volume();
void
Tampil1() // Displays private data of object.
{
cout<<"x =
"<<this->x<<", y =
"<<this->y<<", z = "
<<(*this).z <<endl;
}
void
Tampil2()
{cout << this<<endl;}
//menghasilkan nilai dari this
private:
int
x, y, z; //data private
}; //akhir dari
kelas Kubik
int
Kubik::luas_permukaan() //definisi dari luas_permukaan()
{
return
2*(x*y +y*z +z*x);
}
int
Kubik::volume() //definisi
dari volume()
{
return
x*y*z;
}
int main()
{
Kubik C1(5,6,4), C2(7,8,5) ; //C1 dan C2
adalah objek dari Kubik
C1.Tampil1();
C1.Tampil2(); //nilai dari pointer this untuk C1
cout<<&C1<<endl; //alamat dari C1
C2.Tampil1();
C2.Tampil2(); //nilai dari pointer this untuk C2
cout<<&C2<<endl; //alamat dari C2
cout<<"Volume dari Kubik C1 =
"<<C1.volume()<<"\n";
cout<<"Volume dari Kubik C2 =
"<<C2.volume()<<"\n";
cout<<"Luas permukaan dari C1 =
"<<C1.luas_permukaan()<<"\n";
cout<<"Luas permukaan dari C2 =
"<<C2.luas_permukaan()<<"\n";
return
0 ;
}
|
KELUARAN
|
|
x = 5, y = 6, z
= 4
0018FF3C
0018FF3C
x = 7, y = 8, z
= 5
0018FF30
0018FF30
Volume dari
Kubik C1 = 120
Volume dari Kubik
C2 = 280
Luas permukaan
dari C1 = 148
Luas permukaan
dari C2 = 262
|
Dari keluaran program, terlihat jelas bahwa nilai dari pointer this dan alamat dari objek-objek adalah
sama. Selain itu, statemen (*this).z
dipakai untuk menentukan nilai dari data z dari objek. Pointer this menunjuk ke objek kelas.
3.9 Anggota
Data Statis dari Kelas
Objek-objek dari suatu kelas memiliki salinan sendiri atas anggota-anggota
data dari kelas. Pada beberapa situasi tertentu, sejumlah data bisa jadi sama
untuk semua objek kelas. Pada kasus itu, daripada setiap objek memiliki salinan
sendiri dari data objek, akan lebih mudah bila hanya ada satu salinan data yang
dipakai bersama oleh semua objek kelas, karena ini akan menghemat memori,
khususnya ketika data yang dipakai bersama itu cukup besar. Untuk aplikasi
semacam itu, data bersama itu perlu dideklarasikan static. Data statis dapat dideklarasikan bersamaan dengan salah
satu dari ketiga penspesifikasi akses, yaitu public, protected, atau private. Data statis publik dapat
diakses secara langsung oleh setiap objek kelas karena data statis dipakai
bersama oleh semua objek. Anggota data statis yang dideklarasikan private atau
terproteksi dapat diakses melalui fungsi-fungsi publik dari kelas.
Pendeklarasian data statis diawali dengan katakunci static. Hal ini diilustrasikan oleh program berikut.
Program 3.13 Mengilustrasikan pendeklarasian
anggota statis di dalam sebuah kelas
|
|
|
#include <iostream>
using namespace std;
class Kubik{
public:
static int x; //x dideklarasikan static
Kubik(int W ): y(W) {} //konstruktor
static
void Tampil() //fungsi statis
{
cout<<"Tinggi dari semua
objek adalah = "<<z<<endl;
}
int
luas_permukaan();
int
volume();
private:
int
y;
static
int z; //variabel statis
}; //akhir dari
kelas Kubik
int Kubik :: x =
10;
int Kubik :: z =
5;
int
Kubik::luas_permukaan()
{
return
2*(x*y +y*z +z*x);
}
int
Kubik::volume()
{
return
x*y*z;
}
int main()
{
Kubik C1(6), C2(3);
cout<<"C1.x =
"<<C1.x<<", C2.x = "<<C2.x <<endl;
Kubik::Tampil(); //pemanggilan fungsi
tanpa objek
cout<<"Volume dari Kubik C1
" <<C1.volume()<<"\n";
cout<<"Volume dari Kubik C2 =
"<<C2.volume()<<"\n";
cout<<"Luas permukaan dari C1 =
"<<C1.luas_permukaan()<<"\n";
cout<<"Luas permukaan dari C2 =
"<<C2.luas_permukaan()<<"\n";
return
0 ;
}
|
KELUARAN
|
|
C1.x = 10, C2.x
= 10
Tinggi dari
semua objek adalah = 5
Volume dari
Kubik C1 300
Volume dari
Kubik C2 = 150
Luas permukaan
dari C1 = 280
Luas permukaan
dari C2 = 190
|
Pada program di atas, dua anggota data x dan z dideklarasikan static. Variabel int x dideklarasikan static
di bawah domain publik sedangkan variabel int
z dideklarasikan static di bawah
domain private. Data x (sebuah anggota publik) dapat diakses secara langsung
oleh objek kelas. Lihat keluaran C1.x =
10 dan C2.x = 10, pada baris
pertama keluaran program. Data statis yang dideklarasikan private tidak dapat
diakses secara langsung oleh objek. Ia hanya bisa diakses melalui fungsi publik
sama seperti anggota data private biasa. Pada program tersebut, hal ini
diilustrasikan oleh fungsi Tampil()
yang menampilkan nilai dari z.
3.10 Anggota
Fungsi Statis dari Kelas
Anggota fungsi dari suatu kelas dapat pula dideklarasikan static jika argumen-argumennya juga
dideklarasikan static atau jika
fungsi itu tidak mengakses sembarang anggota tak-statis dari kelas. Pointer this yang berkaitan dengan setiap objek
kelas hanya dapat diterapkan pada anggota fungsi tak-statis dari kelas. Anggota
fungsi statis dari kelas tidak memiliki pointer this. Program berikut mengilustrasikan aplikasi dari sebuah fungsi
statis dengan parameter-parameter statis.
Program 3.14 Mengilustrasikan fungsi
anggota statis dari sebuah kelas
|
|
|
#include <iostream>
using namespace std;
class Kubik {
public:
Kubik(int H):z(H) {} //konstruktor
static
int luas_dasar(){return x*y;} //fungsi statis
int
luas_permukaan();
int
volume( );
private:
static
int x , y; //x dan y dideklarasikan static
int
z ;
}; //akhir dari
kelas Kubik
int Kubik :: x =
5; //anggota data statis
int Kubik :: y =8
; //anggota data statis
int
Kubik::luas_permukaan() //definisi dari luas_permukaan()
{
return
2*(x*y +y*z +z*x);
}
int
Kubik::volume() //definisi
dari volume()
{
return
x*y*z;
}
int main()
{
Kubik C1(5), C2(8) ;
cout<<"Luas dasar dari semua
objek = "<<Kubik::luas_dasar()<<endl;
cout<<"Volume dari Kubik C1
" <<C1.volume()<<"\n";
cout<<"Volume dari Kubik C2 =
"<<C2.volume()<<"\n";
cout<<"Luas permukaan dari C1 =
"<<C1.luas_permukaan()<<"\n";
cout<<"Luas permukaan dari C2 =
"<<C2.luas_permukaan()<<"\n";
return
0 ;
}
|
KELUARAN
|
|
Luas dasar dari
semua objek = 40
Volume dari
Kubik C1 200
Volume dari
Kubik C2 = 320
Luas permukaan
dari C1 = 210
Luas permukaan
dari C2 = 288
|
3.11 Pengelolaan
Memori Dinamis Untuk Objek-Objek Kelas
OPERATOR NEW DAN DELETE DAN NEW[] DAN DELETE[]
Operatot new mengalokasikan
memori dari tempat penyimpanan bebas yang dinamakan dengan heap sedangkan operator
delete melakukan kebalikannya, yang
membebaskan memori dengan menghapus objek. Memori yang dibebaskan dikembalikan
ke heap untuk kegunaan lain. Untuk pengalokasian memori untuk array, Anda
memiliki operator new[] dan operator
delete[] untuk menghapus array dan membebaskan
memori. Untuk objek-objek kelas, operator new
dipakai untuk mengalkasikan memori bagi objek tunggal sedangkan operator new[] dipakai untuk menciptakan sebuah
array yang memuat objek-objek. Jadi, objek tunggal dihapus dari memori
menggunakan operator delete dan
array objek dihapus dengan operator delete[].
Harus diperhatikan bahwa ketika new[]
digunakan untuk pengalokasian memori, untuk membebaskan memori Anda perlu
menggunakan delete[] dan bukan hanya
delete. Sebagai contoh, jika Anda
telah menciptakan sebuah array objek menggunakan new[] dan jika Anda hanya menggunakan delete untuk menghapus array, maka operator delete itu hanya menghapus objek pertama dari array dan objek-objek
lainnya tidak terhapus. Jadi, pembebasan memori hanya parsial. Program berikut
mengilustrasikan aplikasi dari operator new
dan delete untuk objek-objek kelas.
Program 3.15 Mengilustrasikan penggunaan
operator new dan delete untuk objek kelas
|
|
|
#include <iostream>
using namespace std;
class List{
private:
double
x ; // x = berat dalam kg, y = harga per kg
double
y;
public:
void
set_data(double a, double b )
{x = a; y = b;}
void
Tampil()
{
cout<<"Berat = ";
cin>>x;
cout<<"Harga = ";
cin>>y;
cout<<"Harga dari
"<<x<<" kg dengan biaya "<<y<<"
per kg = "<<x*y<<endl;
}
};
void main()
{
double
i,j;
List *ptr= new List ; //menggunakan operator new
(*ptr).set_data(i,j);
ptr -> Tampil(); //(*ptr) dan ptr->
ekivalen
delete
ptr;
}
|
KELUARAN
|
|
Berat = 34.5
Harga = 3.3
Harga dari 34.5
kg dengan biaya 3.3 per kg = 113.85
|
Program berikut mengilustrasikan aplikasi dari new[] dan delete[].
Program 3.16 Mengilustrasikan penggunaan
operator new[] dan delete[] untuk array objek
|
|
|
#include <iostream>
using namespace std;
class List {
private:
int
x,y; //x = jumlah item, y = harga per item
public:
void
set_data(int a, int b)
{
x = a;
y = b;
}
void
Tampil()
{
cout<<"Jumlah item =
"; cin>>x;
cout<<"Harga tiap item =
"; cin>>y;
cout<<"Biaya dari "<<x<<" buah item dengan
harga "<<y<<" per item = "<<x*y<<endl;
}
}; //akhir dari
kelas List
void main()
{
List *ptr= new List[3]; //pointer ke kelas List
for
(int k=0; k<3; k++)
{
cout<<"Untuk nomor item
" <<k+1<<endl;
int
i=0,j=0; //user memasukkan data
(*ptr).set_data(i,j);
ptr -> Tampil();
} // (*ptr) dan ptr-> ekivalen
delete[]
ptr;
}
|
KELUARAN
|
|
Untuk nomor
item 1
Jumlah item =
34
Harga tiap item
= 45
Biaya dari 34
buah item dengan harga 45 per item = 1530
Untuk nomor
item 2
Jumlah item =
65
Harga tiap item
= 54
Biaya dari 65
buah item dengan harga 54 per item = 3510
Untuk nomor
item 3
Jumlah item =
76
Harga tiap item
= 76
Biaya dari 76
buah item dengan harga 76 per item = 5776
|
3.12 Kelas
Matriks
Kelas berikut berkaitan dengan matriks. Fungsi-fungsi seperti penjumlahan,
pengurangan, atau perkalian matriks dicantumkan di dalam program utama.
Program 3.17 Mengilustrasikan penjumlahan,
pengurangan, dan perkalian matriks
|
|
|
#include <iostream>
using namespace std;
class Matriks
{
private:
int
m, n;
public:
int**
Ptr;
Matriks (int B , int K)
{
m = B, n = K ; // B untuk baris dan
K untuk kolom
Ptr = new int *[m];
for(int i =0; i<m; i++)
Ptr[i] = new int [n];
}
// Nil_E untuk nilai elemen
void
Baca_Elemen()
{
cout<<"Masukkan
elemen-elemen dari matriks
"<<m<<"x"<<n<<": ";
int
Nil_E =0;
for(int b =0; b< m; b++)
for (int k =0;
k<n;k++)
{
cin>>Nil_E;
Ptr[b][k] = Nil_E;
}
}
void
Tulis_Elemen()
{
for(int s=0; s<m; s++)
{
for(int p=0; p<n;
p++)
cout<<Ptr[s][p]<<"\t ";
cout<<endl;
}
}
};
int main()
{
Matriks A(3,3), B(3,3), K(3, 3), D(3,3), E(3,3);
cout<<"Masukkan elemen-elemen
dari matriks A dan B.\n";
A.Baca_Elemen();
B.Baca_Elemen();
cout <<"Untuk matriks A, Anda
memasukkan elemen-elemen berikut: \n";
A.Tulis_Elemen( );
cout <<"Untuk matriks B, Anda
memasukkan elemen-elemen berikut: \n";
B.Tulis_Elemen( );
cout<<"A.Ptr[1][0] = "
<< A.Ptr[1][0]<< endl;
for
(int k = 0; k<3; k++ )
for
( int p =0; p<3; p++)
{
K.Ptr[k][p] = A.Ptr[k][p] +
B.Ptr[k][p]; //penjumlahan matriks
D.Ptr[k][p] = A.Ptr[k][p] -
B.Ptr[k][p]; //pengurangan matriks
}
for(int J = 0; J<3; J++) //perkalian
matriks
for(int
K=0; K<3; K++)
{
E.Ptr[J][K] = 0;
for
(int S =0; S<3; S++)
E.Ptr[J][K] += A.Ptr[J][S] *
B.Ptr[S][K];
}
//Statemen-statemen keluaran
cout<<"Matriks K = Matriks A +
Matriks B: "<<endl;
cout<<"Elemen-elemen dari
matriks K adalah berikut: "<<endl;
K.Tulis_Elemen();
cout<<"untuk matriks D =
Matriks A - Matriks B :"<<endl;
cout<<"Elemen-elemen dari
matriks D adalah berikut: "<<endl;
D.Tulis_Elemen();
cout<<"untuk matriks E =
Matriks A * Matriks B :"<<endl;
cout<<"Elemen-elemen dari
matriks E adalah berikut: "<<endl;
E.Tulis_Elemen();
return
0;
}
|
KELUARAN
|
|
Masukkan
elemen-elemen dari matriks A dan B.
Masukkan
elemen-elemen dari matriks 3x3: 1 2 3 4 5 6 7 8 9
Masukkan
elemen-elemen dari matriks 3x3: 10 20 30 40 50 60 70 80 90
Untuk matriks
A, Anda memasukkan elemen-elemen berikut:
1 2 3
4 5 6
7 8 9
Untuk matriks
B, Anda memasukkan elemen-elemen berikut:
10 20
30
40 50
60
70 80
90
A.Ptr[1][0] = 4
Matriks K =
Matriks A + Matriks B:
Elemen-elemen
dari matriks K adalah berikut:
11 22
33
44 55
66
77 88
99
untuk matriks D
= Matriks A - Matriks B :
Elemen-elemen
dari matriks D adalah berikut:
-9 -18
-27
-36 -45
-54
-63 -72
-81
untuk matriks E
= Matriks A * Matriks B :
Elemen-elemen
dari matriks E adalah berikut:
300 360
420
660 810
960
1020 1260
1500
|
LATIHAN
- Apa itu fungsi friend untuk suatu kelas?
- Apakah yang menjadi hak dari fungsi friend?
- Bagaimana fungsi friend dideklarasikan dan didefinisikan?
- Bagaimana mendeklarasikan sebuah kelas friend?
- Apa karakteristik-karakteristik dari sebuah kelas friend?
- Apa itu anggota data statis dari sebuah kelas?
- Apa itu anggoa fungsi statis dari sebuah kelas? Tuliskanlah kode untuk mengilustrasikan pendeklarasian sebuah anggota fungsi statis dari suatu kelas?
- Apa perbedaan antara anggota data statis dari sebuah kelas dan anggota data konstan dari suatu kelas?
- Bagaimana Anda mendeklarasikan dan menginisialisasi anggota data statis dari suatu kelas?
- Apa itu pointer this? Bagaimana pointer itu berelasai dengan objek kelas?
- Berikan contoh kode dimana di dalamnya pointer this secara eksplisit digunakan.
- Berikan contoh kode yang mendeklarasikan sebuah pointer yang menunjuk ke fungsi anggota dari sebuah kelas.
- Bagaimana Anda mendeklarasikan sebuah pointer yang menunjuk ke objek dari sebuah kelas.
- Bagaimana Anda mendeklarasikan pointer yang menunjuk ke anggota data dari sebuah kelas? Tuliskan kode untuk mengilustrasikannya.
- Fungsi kelas mana yang dipanggil ketika sebuah objek kelas diciptakan dan fungsi mana yang dipanggil untuk menghapusnya?
- Apa gunanya operator new dan operator new[]? Tuliskan kode untuk mengilustrasikannya.
- Apa yang Anda pahami tentang pengelolaan memori dinamis?
- Tuliskan sebuah program yang mengilustrasikan pendeklarasian pointer yang menunjuk ke objek kelas.
- Tuliskan sebuah program yang mengilustrasikan pendeklarasian pointer yang menunjuk ke anggota fungsi kelas.
- Tuliskan sebuah program yang mengilustrasikan pendeklarasian pointer yang menunjuk ke kelas.
No comments:
Post a Comment