Xedi.Xermawan's Blog

personal-technical blog

Menengok kembali: C++ virtual function

with 4 comments

edi ermawan, https://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

#include <iostream>

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();
}

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

Written by XediXermawan

May 15, 2010 at 3:17 pm

Posted in C/C++ Diary

Tagged with , ,

4 Responses

Subscribe to comments with RSS.

  1. artikel yang bagus dan menambah wawasan tentang C++ yang advance….terima kasih

    agus

    February 3, 2012 at 4:10 am

  2. belajar C++, google nemu blog mu haha
    makasi bro Xedy

    Rocky

    November 25, 2015 at 12:25 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: