Menengok kembali: C++ virtual function

edi ermawan, http://offground.wordpress.com

Fungsi Virtual. Alasan kenapa sebuah fungsi perlu dibuat virtual adalah agar fungsi tersebut bisa di-deklarasikan ulang di kelas turunannya ( meng-override fungsi ) **dan **jika kamu ingin me-resolve pemanggilan body function saat runtime ( late binding/ dynamic binding ). perhatikan kata dihubungkan dengan “dan” bold mode : ) . Karena member fungsi tanpa virtual pun juga bisa di-override. Bedanya jika sebuah fungsi itu tidak virtual dan dideklarasikan ulang di kelas turunan, ketika fungsi itu dijalankan , maka “body function” yang akan dijalankan adalah sesuai yang didefinikan. ( body function yang akan dipanggil sudah ditentukan / di-resolve saat compile time , atau yang disebut static binding ).

fungsi virtual :

  1. 

Anggota dari sebuah kelas

  2. 

Dideklarasikan dengan awalan virtual

  3. 

Fungsi virtual yang di-override dikelas turunannya, pada umumnya berbeda implementasinya dengan virtual fungsi di kelas induk. ( masih memiliki nama fungsi dan jumlah argument yang sama tentunya )

  4. 

Fungsi bisa dibedakan type kelas mana yang memanggil saat runtime

Untuk memahami secara jelas, sepertinya sangat perlu untuk dicoba :). Misalnya terdapat sebuah kelas dasar bernama DrawableObject, yang merupakan kelas dasar untuk semua objek bangun 2D (persegi, lingkaran, segitiga).

vfgbr1

Output dari main program Gbr E :

draw bangun persegi

draw bangun lingkaran

draw bangun persegi

Dari output, dapat dilihat bahwa pemanggilan ->Draw() di instance bangun1 dan bangun2 ( yang awalnya dideklarasikan sebagai DrawableObject class ), secara otomatis memanggil implementasi dari data yang ditunjuk oleh bangun1 dan bangun2 saat runtime. Misalnya kita menghapus “virtual” di class DrawableObject ( Gbr A ), Output program dari main program (Gbr E) menjadi sebagai berikut :

draw dari base class

draw dari base class

draw bangun persegi

dapat dilihat bangun1,bangun2,bangun3 akan memanggil “body function” sesuai apa yang dideklarasikan, dalam hal ini bangun1 dan bangun2 adalah DrawableObject, sedangkan bangun3 adalah persegi.

Dengan karakteristik ini, Fungsi virtual sangat berguna untuk mendesain sebuah code yang bermaksud “menyembunyikan” implementasi fungsi yang memiliki nama yang sama. Contoh penggunaan yang lain ada di Gbr F.

Output dari main program Gbr F :

draw bangun persegi

draw bangun lingkaran

draw bangun Segitiga

draw bangun Segitiga

draw bangun persegi

Di Java, fitur semacam fungsi virtual ini dinamakan Interface. ( saya jarang menulis code di Java, tapi dulu pernah coba ). Namun Interface di Java, body function dari base class-nya harus kosong ( cmiiw ). Kita bisa membuat semacam itu di C++ dengan mengosongkan body dari virtual function di base class . Class semacam ini dinamakan abstract base class (ABC) atau pure virtual function . ABC tidak bisa di-instance-kan secara langsung, hanya bisa sebagai pointer ke turunannya. Contoh ABC :

vfgbr2

meng-instance-kan class ABC secara langsung, akan compile-error :

vfgbr3

Di non-ABC, kalau kita ingin memanggil implementasi fungsi di base class dari kelas turunannya bisa dilakukan dengan :

vfgbr4

Output dari main program gbr pertama ( Gbr E ) dengan class Persergi diatas :

draw dari base class

draw bangun persegi

draw bangun lingkaran

draw dari base class

draw bangun persegi

*Virtual Destructor*

untuk mencegah memory leak, destructor harus virtual jika memenuhi keadaan sebagai berikut : sebuah kelas X diturunkan dari kelas induk Y dimana kelas X memiliki sesuatu yang penting yang harus dieksekusi di destructor ( misalnya anggota kelas berupa pointer yang harus di delete di destructor ). Dengan menambahkan keyword “virtual” di destructor Y, destructor Y dan destructor X dipanggil. Lebih jelas dicontoh berikut ini

[sourcecode language=“cpp”] #include

class A { public: A() { std::cout << “A”; } ~A() { std::cout << “~A”; } };

class B :public A { private: int* memberPtr; public: B() { memberPtr = new int(); } ~B() { std::cout << “~B”; delete memberPtr; } };

void testCase1() { B* inst; inst = new B(); delete inst; }

void testCase2() { A* inst; inst = new B(); delete inst; } int main() { testCase1(); testCase2(); } [/sourcecode]

tanpa keyword “virtual” di kelas induk A :

testCase1()   OK , destructor B dipanggil,kemudian destructor A dipanggil

testCase2()   NOT OK, karena destructor B tidak dipanggil .hanya destructor A yang dipanggil

Performance Cost dari virtual function

karena virtual function sebenarnya adalah penambahan indirection ( memanggil fungsi dari vtable ) maka tentu ada cost nya, walaupun mungkin sangat kecil ( belum pernah memprofile sendiri ) 

05/15/10-07:44:34 PM-eof-

updated : 11/27/2014  11:53 PM

Download PDF version

comments powered by Disqus