Pure Virtual

คือจาก เมื่อวันที่ผ่านมา เนื่องจากว่า งานที่ทำอยู่มีส่วนต้องให้ port โปรแกรมจาก Win มาสู่ mac และบังเอิญว่า ผม compile แล้วมันผ่าน แต่ว่าตอน Runtime มันดัน Error สิ่งที่มันบอกมาก็คือว่า pure virtual method called terminated called with out an active exception ปัญหาที่เกิดขึ้น ก็ยัง งงๆๆว่าเป็นเพราะอะไร แต่พอหลังจากให้เพื่อนมาดูแล้วก็นั่งถกกัน ว่ามันเกิด เฉพาะกับ mac หรือเปล่าเพราะว่าใน win ไม่เห็นมันจะเกิด ก็เลยทำการเขียน code ที่ทำงานแบบเดียวกัน ก็ัดังตัวอย่างข้างล่าง

#include <stdio.h>
class Base;
void foo(Base*);
class Base
{
	public:
		Base(){};
		virtual ~Base()
		{
			foo(this);
		}
		virtual void banana() = 0;
};
 
void foo(Base* base)
{
	base->banana();
}
 
class Derived: public Base
{
	public:
		Derived(){}
		~Derived(){}
		void banana()
		{
			std::cout << "Banana";
		}
};
 
int main (int argc, char * const argv[])
{
 
	Derived* test = new Derived();
	std::cout << "Hello, World!\n";
	delete test;
	return 0;
 
}

ก็ถ้า ดูตาม code ก็จะเห็นว่า มี Base กับ Derived เนื่องจากว่า Base Class มันเป็น Pure Virtual (Abtract Class) เราต้อง implement ส่วนของ code การทำงานใน derived class เสมอไม่อาจจะเขียน implement ใน Base Class ได้ และปัญหาจากโปรแกรมข้างบนเกิดขึ้นเพราะในขณะที่ base class ได้เรียก destructor ของตัวเองนั้น มันกลับไปเรียกใช้งานฟังชั่นใน derived class ด้วย ซึ่งนั่นก็ทำให้มันเกิด error เพราะว่า derived class ได้ถูกทำลายไปก่อนแล้ว ทำให้ไม่สามารถเรียกได้

ลองดูตรง

virtual ~Base()
{
	foo(this);
}

จาก destructor นี้จะเห็นว่า มีการเรียกฟังก์ชั่น foo และแน่นอนว่า foo ไปเรียก

base->banana();

อีกที สืบเนื่องจากว่ามันเป็น pure virtual แปลว่าตัว Base Class เองไม่อาจจะเขียน implement code ได้มันจึงต้องไปเรียก banana ในตัว Derived Class ที่มีการเขียน implement code และ Derived นั้นได้ทำลายจาก destructor ไปเรียบร้อยแล้ว มันเลยไม่เจอ banana ทำให้เกิด error นั่นเอง

ลองศึกษา เพิ่มเติมเกี่ยวกับ Virtual Function ได้ที่ http://en.wikipedia.org/wiki/Virtual_function

Technorati Tags: , , ,


Leave a Reply

You must be logged in to post a comment.