Friend PEMROGRAMAN BERORIENTASI OBJEK

542 Direktorat Pembinaan SMK | 2008 CRectangle rect, rectb; rect.set_values 2 , 3 ; rectb = duplicate rect; cout Hasil nya = rectb.area; } Dari fungsi duplicate yang merupakan friend dari CRectangle, kita dapat mengakses member width dan height dari objek yang berbeda dalam tipe CRectangle. Perhatikan bahwa fungsi duplicate bukan merupakan anggota dari class CRectangle Dengan friend function fungsi yang bukan merupakan anggota class diliar class dapat mengakses member class yang sifatnya privateprotected. Secara umum penggunaan fungsi friend kelihatannya keluar dari metodologi OOP, sehingga selama masih memungkinkan lebih baik menggunakan member yang classnya sama untuk masalah ini. Seperti pada contoh sebelumnya, akan lebih sederhana jika duplicate diletakkan dalam class CRectangle. Program 16.13 include iostream.h include conio.h class contoh { int x; void fcontoh; public: void fcontoh1 ; void fcontoh2 ; friend void fcontoh3 ; }; void contoh::fcontoh { cout \nFungsi fcontoh anggota class contoh, bersifat private ; } void contoh::fcontoh1 { x= 3 ; cout Fungsi contoh 1 anggota class contoh ; fcontoh; cout \nNilai x = x;} void contoh::fcontoh2 { cout \n\nFungsi contoh 2 anggota class contoh ; cout \nNilai x = x;} 2008 | Direktorat Pembinaan SMK 543 void fcontoh3 { contoh b; b.x= 10 ; cout \n\nFungsi contoh 3 bukan anggota class contoh ; cout \ntetapi merupakan fungsi friend dari class contoh ; cout \nsehingga dapat mengakses x yang sifatnya private ; cout \ndan mengakses fcontoh yang juga bersifat private ; b.fcontoh; cout \nNilai x = b.x;} main { contoh a; a.fcontoh1; a.fcontoh2; fcontoh3; getch; } Telah diketahui bahwa tujuan utama dari pemrograman berorientasi obyek adalah enkapsulasi data dan fungsi yang mengakses data di dalam class. Pengkapsulan memberikan keuntungan terutama memudahkan dalam pemeliharaan program dan juga dalam debugging. Namun pengkapsulan untuk obyek yang kompleks terkadang sulit dilakukan, sehingga adakalanya aturan terpaksa harus dilanggar demi tujuan yang harus dicapai. Seperti jika punya rumah ada kamar yang sifatnya pribadi, sehingga tidak dimasuki oleh orang lain. Tetapi kadang justru seorang teman yang dianggap sahabat boleh memasuki kamar tersebut, itulah analogi dari friend. Friend pada C++ memang kontradiksi. Disatu pihak dapat menyederhanakan kompleksitas suatu obyek, tetapi juga dapat meruntuhkan konsep enkapsulasi, tentu saja jika terlalu banyak digunakan. Hal ini disebabkan karena friend memungkinkan pihak di luar class dapat mengakses anggota class termasuk yang bersifat private. Itulah sebabnya friend harus digunakan seperlunya dan juga digunakan secara tepat. Apabila ternyata kita terlalu banyak menggunakan friend maka sebaiknya merombak rancangan program class yang telah dibuat. Sebaiknya class- class yang menggunakan friend dipecah menjadi beberapa class lain. Secara umum, friend berguna kalau ada suatu operasi yang hendak mengakses data dari dua class yang tidak ada kaitannya. Friend juga memungkinkan untuk menampilkan isi obyek lain. Salah satu fungsi friend adalah fungsi bukan anggota class yang dapat mengakses anggota class. 544 Direktorat Pembinaan SMK | 2008 Fungsi ini dapat dipakai untuk mengakses anggota class yang bersifat private maupun protected. Gambaran fungsi friend dapat dilihat pada program berikut: Program 16.14 include cstdlib include iostream using namespace std; include cstdlib include iostream using namespace std; class Siswa { private: char Nama; char Kelas; int NIS; public: Siswa; void inisialisasiint Nomor, char Nama, char Kelas; friend void tampil_dataSiswa swa; }; Siswa::Siswa { NIS = ; Nama = ; Kelas = ; } void Siswa::inisialisasiint Nomor,char Nama, char Kelas { Siswa::NIS = Nomor; Siswa::Nama = Nama; Siswa::Kelas = Kelas; } void tampil_dataSiswa swa { 2008 | Direktorat Pembinaan SMK 545 cout Nomor Siswa = swa.NISendl; cout Nama Siswa = swa.Namaendl; cout Kelas Siswa = swa.Kelasendl; } int mainint argc, char argv[] { Siswa sis; sis.inisialisasi 1234 , Badu , X IPS ; tampil_datasis; system PAUSE ; return EXIT_SUCCESS; } Keluaran dari program di atas adalah sebagai berikut: Nomor Siswa = 1234 Nama Siswa = Badu Kelas Siswa = X IPS Pada contoh di atas, fungsi tampil_data pada class Siswa dideklarasikan sebagai fungsi friend. Dengan demikian, fungsi ini dapat mengakses data seperti NIS. Perhatikan saat fungsi ini didefinisikan, terlihat bahwa fungsi ini seperti fungsi biasa bukan fungsi dari anggota class. Tidak didahului dengan: Siswa:: di depan nama fungsi. Oleh karena fungsi tampil_data berkedudukan sebagai fungsi biasa maka cara pemanggilannya juga mengikuti kaidah fungsi biasa, seperti: tampil_datasis; tidak diperbolehkan menyebut nama class di depan fungsi tersebut seperti contoh berikut: sis.tampil_data; seperti layaknya memanggil fungsi sebuah class. Jadi fungsi friend dianggap sebagai argument biasa bukan anggota suatu class. Sebuah contoh lain mengenai fungsi friend ditunjukkan pada program berikut. Contoh ini menggambarkan fungsi friend yang dapat mengakses tiga buah obyek sekaligus. Program 16.15 include cstdlib include iostream using namespace std; 546 Direktorat Pembinaan SMK | 2008 class HasilUjian { private: int NIS; double Nilai; public: HasilUjianint Nomor, double Nil; friend double nilai_maxHasilUjian a, HasilUjian b, HasilUjian c; }; HasilUjian::HasilUjianint Nomor, double Nil : NISNomor, NilaiNil { } double nilai_maxHasilUjian a, HasilUjian b, HasilUjian c { double maks = a.Nilai; maks = b.Nilai maks ? b.Nilai : maks; maks = c.Nilai maks ? c.Nilai : maks; return maks; } int mainint argc, char argv[] { HasilUjian amir 1234 , 78.6 ; HasilUjian endah 1237 , 88.5 ; HasilUjian siti 1224 , 58.6 ; cout Nilai ujian terbesar : nilai_maxamir,endah,sitiendl; system PAUSE ; return EXIT_SUCCESS; } Keluaran program di atas adalah sebagai berikut: Nilai ujian terbesar : 88.5 Pada program di atas, friend double nilai_maxHasilUjian a, HasilUjian b,HasilUjian c berfungsi mencari nilai terbesar dengan fungsi nilai_max dari tiga obyek a, b, dan c yang merupakan class HasilUjian. Bagaimana untuk pemakaian friend yang lebih dari satu 2008 | Direktorat Pembinaan SMK 547 class ?. Program berikut suatu contoh pemakaian fungsi friend untuk mengakses dua buah class. Ada class PemainWanita dan PemainPria, kemudian ada fungsi friend info_pemain_campuran. Program selengkapnya sebagai berikut: Program 16.16 include cstdlib include iostream using namespace std; class PemainPria; class PemainWanita { private: char nama; char asal; public: PemainWanitachar nam, char asl; friend void info_pemain_campuranPemainWanita x, PemainPria y; }; PemainWanita::PemainWanitachar nam, char asl { nama = nam; asal = asl; } class PemainPria { private: char nama; char asal; public: PemainPriachar nam, char asl; friend void info_pemain_campuranPemainWanita x, PemainPria y; }; PemainPria::PemainPriachar nam, char asl { nama = nam; asal = asl; 548 Direktorat Pembinaan SMK | 2008 } void info_pemain_campuranPemainWanita x, PemainPria y { cout Pemain ganda campuran endl; coutx.nama x.asal endl; couty.nama y.asal endl; } int mainint argc, char argv[] { PemainWanita p_wanita Anna Kournikova , Rusia ; PemainPria p_pria Rafael Nadal , Spanyol ; info_pemain_campuranp_wanita, p_pria; system PAUSE ; return EXIT_SUCCESS; } Keluaran program seperti berikut: Pemain ganda campuran Anna Kournikova Rusia Rafael Nadal Spanyol Pada program di atas ada baris yang berisi: class PemainPria; Pernyataan ini dikenal dengan istilah refernsi di depan. Hal seperti ini diperlukan mengingat pengenal class PemainPria akan digunakan pada pendeklarasian class PemainWanita, yaitu pada baris yang berisi: friend void info_pemain_campuranPemainWanita x, PemainPria y; Deklarasi lengkap PemainPria ini dapat diletakkan di belakang. Hal yang perlu diperhatikan dalam membuat fungsi friend yang melibatkan dua buah class yang berbeda atau lebih adalah mendeklarasikan fungsi tersebut pada class-class yang hendak diakses. Bentuk Pendeklarasiannya persis sama, seperti contoh baris di atas terdapat di kedua class baik PemainWanita maupun PemainPria. Para pemrogram C++ biasa melewatkan obyek pada fungsi friend dengan referensi. Hal seperti ini sangat bermanfaat untuk obyek berukuran besar. Dengan melewatkan secara referensi, prosesnya menjadi lebih cepat. Deklarasi fungsi friend di atas bisa diuah menjadi seperti berikut ini : 2008 | Direktorat Pembinaan SMK 549 friend void info_pemain_campuranconst PemainWanita x, const PemainPria y; Keyword const di atas menunjukkan bahwa anggota obyek tidak dimaksudkan untuk diubah. Sedangkan symbol di depan nama argument x dan y menyatakan obyek tersebut dilewatkan berdasarkan referensi. Selain itu perlu juga disesuaikan pada bagian definisi fungsi, perubahannya sebagai berikut: void info_pemain_campuranconst PemainWanita x, const PemainPria y { ….. } Secara lengkap sebagai berikut: Program 16.17 include cstdlib include iostream using namespace std; class PemainPria; class PemainWanita { private: char nama; char asal; public: PemainWanitachar nam, char asl; friend void info_pemain_campuranconst PemainWanita x, const PemainPria y; }; PemainWanita::PemainWanitachar nam, char asl { nama = nam; asal = asl; } class PemainPria { private: char nama; char asal; 550 Direktorat Pembinaan SMK | 2008 public: PemainPriachar nam, char asl; friend void info_pemain_campuranconst PemainWanita x, const PemainPria y; }; PemainPria::PemainPriachar nam, char asl { nama = nam; asal = asl; } void info_pemain_campuranconst PemainWanita x, const PemainPria y { cout Pemain ganda campuran endl; coutx.nama x.asal endl; couty.nama y.asal endl; } int mainint argc, char argv[] { PemainWanita p_wanita Anna Kournikova , Rusia ; PemainPria p_pria Rafael Nadal , Spanyol ; info_pemain_campuranp_wanita, p_pria; system PAUSE ; return EXIT_SUCCESS; } Keluaran program tetap sama dengan program sebelumnya. Suatu fungsi anggota kelas dapat berkedudukan sebagai fungsi friend. Fungsi seperti ini biasa disebut fungsi anggota friend dapat mengakses anggota class yang mendeklarasikannya. Sebagai contoh program di atas dapat dimodifikasi agar fungsi info_pemain_campuran menjadi fungsi anggota class PemainWanita dan dideklarasikan sebagai frien pada class PemainPria. Mula-mula class PemainWanita perlu dideklarasikan sebagai berikut: Program 16.18 class PemainWanita { private: char nama; 2008 | Direktorat Pembinaan SMK 551 char asal; public: PemainWanitachar nam, char asl; void info_pemain_campuranconst PemainPria x; }; Nampak sekarang bahwa fungsi info_pemain_campuran berkedudukan sebagai fungsi anggota dari class PemainWanita. Argumen dari fungsi ini berupa referensi dari obyek ber-clas PemainPria. Penyebutan class PemainPria mengharuskan adanya pemberitahuan kepada compiler bahwa PemainPria adalah class. Oleh karena itu, sebelum dideklarasikan PemainPria perlu diberikan referensi dimuka seperti contoh program sebelumnya. Kemudian bagaimana pendeklarasian pada class PemainPria ? Pada class ini fungsi info_pemain_campuran dideklarasikan sebagai fungsi friend: Program 16.19 class PemainPria { private: char nama; char asal; friend void PemainWanita::info_pemain_campuranconst PemainPria x; public: PemainPriachar nam, char asl; }; Perhatikan ada perubaha pada fungsi info_pemain_campuran, pada class PemainPria menjadi bersifat private dan memakai keyword friend. Selain itu juga ditambahkan nama class yang menjadi friend yaitu PemainWanita. Program selengkapnya sebagai berikut: Program 16.20 include cstdlib include iostream using namespace std; class PemainPria; class PemainWanita { 552 Direktorat Pembinaan SMK | 2008 private: char nama; char asal; public: PemainWanitachar nam, char asl; void info_pemain_campuranconst PemainPria x; }; PemainWanita::PemainWanitachar nam, char asl { nama = nam; asal = asl; } class PemainPria { private: char nama; char asal; friend void PemainWanita::info_pemain_campuranconst PemainPria x; public: PemainPriachar nam, char asl; }; PemainPria::PemainPriachar nam, char asl { nama = nam; asal = asl; } void PemainWanita::info_pemain_campuranconst PemainPria x { cout Pemain ganda campuran endl; coutnama asal endl; coutx.nama x.asal endl; } int mainint argc, char argv[] { PemainWanita p_wanita Anna Kournikova , Rusia ; PemainPria p_pria Rafael Nadal , Spanyol ; p_wanita.info_pemain_campuranp_pria; 2008 | Direktorat Pembinaan SMK 553 system PAUSE ; return EXIT_SUCCESS; } Apa yang dimaksud dengan class friend ? Sesungguhnya suatu class dapat dijadikan sebagai friend dari class yang lain. Hal seperti ini diperlukan apabila ada dua class dan dibutuhkan mengakses bagian private maupun protected dari class- class tersebut. Kita lihat contoh berikut. Misal ada dua kelas yaitu D3 dan S1, keduanya mempunyai data tentang banyaknya ruang atau kebutuhan ruang kelas. Serta ruangan D3 dapat dipakai oleh S1, maka pendeklarasian masing-masing class sebagai berikut: Program 16.21 class D3 { private: int ruangD3; public: D3 { ruangD3 = 10 ; } friend class S1; }; class S1 { private: int ruangS1; public: S1 { ruangS1 = 6 ; } void info_ruangD3 x; }; Pada contoh ini, x adalah obyek dengan class D3 yang menjadi argument fungsi info_ruang pada class S1. Fungsi dimaksud untuk mengakses data ruang_D3 milik obyek xyang ber-class D3. Masalahnya adalah bahwa data ruangD3 bersifat private, sehingga class S1 tidak bisa mengaksesnya. Persoalan yang sama tetap muncul sekiranya keyword private pada class D3 diganti dengan protected. Sebab seperti diketahui, anggota yang bersifat protected hanya bisa diakses kalau class ini diwariskan ke class turunan. Solusinya dengan class friend seperti yang terlihat pada baris dibawah konstructor D3. Dan dengan pernyataan ini dapat diletakkan dimana saja pada class 554 Direktorat Pembinaan SMK | 2008 D3, private, protected, maupun public. Keluaran program di atas sebagai berikut: Ruang D3 = 10 Ruang S1 = 6 Total Ruang S1 = 16

16.5. Friend class

Sebagaimana kita dapat mendefinisikan friend function, kita juga dapat mendefinisikan class sebagai friend dari class lain, yang mengijinkan satu class mengakses member private dan protected dari class lainnya. Program 16.22 include cstdlib include iostream using namespace std; class CSquare; class CRectangle { int width, height; public: int area void {return width height;} void convert CSquare a; }; class CSquare { private: int side; public: void set_side int a {side=a;} friend class CRectangle; }; void CRectangle::convert CSquare a { width = a.side; height = a.side; } int main { CSquare sqr; CRectangle rect; 2008 | Direktorat Pembinaan SMK 555 sqr.set_side 4 ; rect.convertsqr; cout Hasilnya = rect.area \n ; system PAUSE ; return EXIT_SUCCESS; } Keluaran program diatas adalah sebagai berikut: Hasilnya = 16 Dalam contoh ini kita mendeklarasikan CRectangle sebagai friend dari CSquare, sehingga CRectangle dapat mengakses member private dan protected yang dimiliki class CSquare, yakni CSquare::side, yang mendefinisikan lebar dari segiempat. Kita juga melihat adanya instruksi baru di awal program, yakni class CSquare; yang merupakan prototype dari class CSquare. Hal ini diperlukan karena dalam deklarasi CRectangle kita mengacu kepada CSquare sebagai parameter dalam fungsi convert . Definisi CSquare disertakan di bagian akhir, sehingga jika kita tidak mengikutkan prototype CSquare diawal class instruksi tersebut akan dianggap salah tidak dikenali. Perhatikan bahwa penggunaan friend tidak akan berfungsi jika kita tidak menuliskannya secara eksplisit. Dalam contoh CSquare, CRectangle tidak dianggap sebagai suatu friend class, sehingga CRectangle dapat mengakses member private dan protected milik CSquare tetapi tidak sebaliknya. Agar dua buah class dapat saling mengakses member private dan protected nya maka keduanya harus dideklarasikan sebagai friend class dari yang lain seperti pada contoh berikut: Program 16.23 include iostream.h include conio.h class contoh { int x; public: void fcontoh1 ; void fcontoh2 ; friend class cth; }; class cth { int y;