مخرب یا desutructor کلاس به شکل virtual - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

مخرب یا desutructor کلاس به شکل virtual

+4 امتیاز
چرا بعضی وقت ها destructor کلاس به شکل virtual تعریف میشه ؟
سوال شده بهمن 30, 1392  بوسیله ی SARA (امتیاز 50)   3 9 15
دوباره تگ گذاری شد مهر 9, 1393 بوسیله ی BlueBlade

2 پاسخ

+7 امتیاز
 
بهترین پاسخ

معمولا از Destructor ها برای آزاد کردن حافظه های اختصاص یافنه کلاس ها و کارهای پاک سازی اونها استفاده میشه .

این کد رو نگاه کن :

 

#include <iostream>

using namespace std;

class Base
{
public :
	Base() { cout<<"Base::Base()"<<endl; }
	~Base() { cout<<"Base:~Base()"<<endl; }
};

class Derived : public Base
{
public:
	Derived() { cout<<"Derived::Derived()"<<endl; }
	~Derived() { cout<<"Derived::~Derived()"<<endl; }
};

int main ()
{
	Derived* obj = new Derived;
	delete obj;

	cin.get();
	return 0;
}

 

اگر شماهمچین کلاس هایی داشته باشید . یعنی اشاره گری از نوع کلاس پایه داشته باشید که در واقع به کلاس

مشتق شده اشاره کنه . وقتی که شما اون اشاره گر رو بخواید delete کنید . چون نوع اشاره گر شما از کلاس پایه هست فقط تابع

Destructor کلاس پایه فراخوانی میشه . تابع Destructor کلاس مشتق شده فراخوانی نمیشه .

برای حل این مشکل شما باید پاید تابع Destructor کلاس پایه رو از نوع virtual تعریف کنید تا این اتفاق نیوفته .

که همین کار رو تو کد بالا انجام بدید میشه این کد .
 

#include <iostream>

using namespace std;

class Base
{
public :
	Base() { cout<<"Base::Base()"<<endl; }
	virtual ~Base() { cout<<"Base:~Base()"<<endl; }
};

class Derived : public Base
{
public:
	Derived() { cout<<"Derived::Derived()"<<endl; }
	~Derived() { cout<<"Derived::~Derived()"<<endl; }
};

int main ()
{
	Base* obj = new Derived;
	delete obj;

	cin.get();
	return 0;
}

 

نتیجه خروجی ها رو باهم مقایسه کنید متوجه میشید .

درباره توابع virtual و override کردن توابع تحقیق کن دلیل اصلیش رو متوجه میشی .

پاسخ داده شده اسفند 1, 1392 بوسیله ی Ali Rahbar (امتیاز 4,240)   6 16 46
انتخاب شد اسفند 1, 1392 بوسیله ی SARA
+2 امتیاز

بصورت خلاصه :

اگر یک کلاس از کلاس مورد نظر مشتق کرده باشید اگر شی کلاس مشتق شده رو داخل اشاره گر به  کلاس پایه ذخیره کرده باشید و بخواهید  یک تابع یا destructor رو  بوسیله این اشاره گر صدا بزنید اگر کلمه virtual موجود نباشه کامپایلر نمیتونه تابع صحیح که مربوط به کلاس مشتق شده هست  رو صدا بزنه .

virtual کاری که می کنه اینه که یک جدول(virtual table) از آدرس ها + ااسم متغیر ها زمان اجرا میسازه بعد بر اساس اون توابع رو صدا میزنه که یکم سرعت پایین تری نسبت به حالت عادی داره

پاسخ داده شده مرداد 20, 1393 بوسیله ی PSPCoder (امتیاز 1,301)   14 40 57
سلام! ممنونم! یه سوال کوچیک... چرا باید اسم متغیر ها در این جدول باشه...؟!
من برای درک بهتر گفتم آدرس + اسم متغیر . پیاده سازی  virtual table  برای هر کامپایلری فرق می کنه و الگوریتم های خاص خودشون رو دارن
...