C++ میں ورچوئل ڈسٹرکٹر

C My Wrchwyl S Rk R



C++ وہ زبان ہے جو پروگرامنگ کے بنیادی تصور میں بنیاد فراہم کرنے کے لیے استعمال ہوتی ہے اور پروگرامرز کی منطقی سوچ کو مضبوط بناتی ہے۔ C++ میں، OOP ایک اہم کردار ادا کرتا ہے کیونکہ OOP ایک آبجیکٹ اورینٹڈ زبان ہے جو کلاسز کی اشیاء تخلیق کرتی ہے۔ OOP میں، ہم کلاسز اور اشیاء کا مطالعہ کرتے ہیں۔ کلاسز میں ڈیٹا ممبرز ہوتے ہیں جو مختلف اقسام اور ممبر کے مختلف افعال کے متغیر ہوتے ہیں۔ مثالوں کی مدد سے، ہم کسی بھی کلاس کے ڈیٹا تک رسائی حاصل کرتے ہیں۔ جب آپ کلاس بناتے ہیں تو ہر کلاس کا اپنا کنسٹرکٹر اور ڈسٹرکٹر ہوتا ہے۔ کنسٹرکٹر خود کو کہا جاتا ہے جب اس کلاس کا آبجیکٹ بنایا جاتا ہے۔ ہم کنسٹرکٹر کے اندر کلاس کے متغیرات کو بھی شروع کر سکتے ہیں۔ کنسٹرکٹر کے ساتھ ڈیسٹرکٹرز بھی خود بخود بن جاتے ہیں لیکن ڈسٹرکٹرز آبجیکٹ کو تباہ کر دیتے ہیں اور یہ آخری فنکشن ہے جسے آبجیکٹ کو تباہ کرنے سے پہلے کہا جاتا ہے۔ کلاس کا نام، مثال کے طور پر 'پیشہ' کلاس، بنایا گیا ہے۔ اس کا کنسٹرکٹر پروفیشن () ہے اور ڈسٹرکٹر ~ پروفیشن () ہے۔ ان تینوں کا ایک ہی نام ہے۔

OOP، کنسٹرکٹرز، اور ڈسٹرکٹرز کے بارے میں بات کرنے کے بعد، آئیے اب ورچوئل ڈسٹرکٹرز کے بارے میں بات کرتے ہیں۔ ورچوئل ڈسٹرکٹرز، جیسا کہ نام بتاتا ہے، آبجیکٹ کو تباہ کر دیتا ہے۔ ہمارے پاس ایک بیس کلاس ہے اور ایک اخذ شدہ کلاس ہے جو بیس کلاس سے اخذ کی گئی ہے۔ دونوں طبقوں کے اپنے کنسٹرکٹر اور ڈسٹرکٹر ہیں۔ ورچوئل ڈسٹرکٹر یادوں کو آزاد کرتا ہے جو اخذ شدہ کلاس آبجیکٹ کے ذریعے الاٹ کیا جاتا ہے جبکہ اخذ شدہ کلاس کی اشیاء کو 'ورچوئل' کلیدی لفظ کے ساتھ بیس کلاس پوائنٹر کا استعمال کرتے ہوئے حذف کیا جاتا ہے۔

ہم ورچوئل ڈسٹرکٹر کیوں استعمال کرتے ہیں؟

جب کلاس ممبر کے فنکشنز کی تکمیل ہو جاتی ہے یا main() طریقہ کار کا عمل ختم ہونے والا ہوتا ہے، تو destructor کو خود بخود اس میموری کو آزاد کرنے کے لیے بلایا جاتا ہے جو آبجیکٹ کی تخلیق کے دوران مختص کی جاتی ہے۔ اب، ہم ورچوئل ڈسٹرکٹر کیوں استعمال کرتے ہیں؟ جب بیس کلاس کو حذف کیا جاتا ہے جو اخذ شدہ کلاس کی طرف اشارہ کرتا ہے، یہاں پوائنٹر (*) استعمال ہوتا ہے۔ بیس کلاس ڈسٹرکٹر کو صرف اس عمل کے دوران بلایا جاتا ہے۔ اخذ شدہ کلاس ڈسٹرکٹر کو نہیں کہا جاتا ہے جو مسائل کی طرف جاتا ہے۔ ان میں سے ایک میموری لیکیج کا مسئلہ ہے۔ اس مسئلے سے بچنے اور اپنے کوڈ کو محفوظ بنانے کے لیے، ہم بیس کلاس ڈسٹرکٹر کو حذف کر کے آبجیکٹ کی تخلیق کے دوران الاٹ کی گئی میموری کی جگہ کو خالی کرنے کے لیے عملی طور پر آبجیکٹ کو تباہ کر دیتے ہیں۔

ورچوئل ڈسٹرکٹر کے بغیر C++ بنیادی مثال

آئیے دیکھتے ہیں کہ پروگرام ایک سادہ پروگرام کے ساتھ ورچوئل ڈسٹرکٹر کے بغیر کیسے کام کرتا ہے جو پوائنٹر کو حذف کر دیتا ہے۔

کوڈ:

# شامل کریں

نام کی جگہ کا استعمال کرتے ہوئے std ;
کلاس Parent_Class0
{
عوام :
پیرنٹ_کلاس0 ( )
{ cout << 'پیرنٹ کلاس کنسٹرکٹر' << endl ; }
~والدین_کلاس0 ( )
{ cout << 'پیرنٹ کلاس ڈسٹرکٹر' << endl ; }
} ;
کلاس چائلڈ_1 : عوامی والدین_کلاس0
{
عوام :
بچہ_1 ( )
{ cout << 'چائلڈ کلاس کنسٹرکٹر' << endl ; }
~بچہ_1 ( )
{ cout << 'چائلڈ کلاس ڈسٹرکٹر' << endl ; }
} ;
int مرکزی ( )
{
پیرنٹ_کلاس0 * پوائنٹر = نیا بچہ_1 ( ) ;
پوائنٹر کو حذف کریں ;
واپسی 0 ;
}

یہ کوڈ بتاتا ہے کہ کوڈ کسی ورچوئل ڈسٹرکٹر کے بغیر کیسے چلتا ہے۔ سب سے پہلے، 'Parent_Class0' کے نام سے ایک کلاس بنائیں جو پیرنٹ کلاس ہوگی۔ اس کلاس کے اندر، ایک کنسٹرکٹر اور ڈسٹرکٹر بنائیں۔ جیسا کہ ہم جانتے ہیں، کنسٹرکٹر اور ڈسٹرکٹر کا نام کلاس کی طرح رکھا گیا ہے۔ ڈسٹرکٹر کی نمائندگی کنسٹرکٹر کی طرح کی جاتی ہے لیکن اس میں ایک علامت (~) ہے جو اسے کنسٹرکٹر سے ممتاز کرتی ہے۔ کنسٹرکٹر اور ڈسٹرکٹر کے اندر، 'cout<<' کا استعمال کرتے ہوئے ایک پیغام پرنٹ کریں۔ اب، ایک اور کلاس بنائیں جو کہ 'Child_1' ہے۔ یہ کلاس پیرنٹ کلاس، 'Parent_Class0' سے ماخوذ ہے۔ اخذ شدہ کلاس میں اس کا کنسٹرکٹر اور ڈسٹرکٹر ہوتا ہے جس میں آؤٹ پٹ اسکرین پر پرنٹ کرنے کا پیغام ہوتا ہے۔

مین () طریقہ میں، ہم 'Parent_Class0' کی ایک مثال بناتے ہیں اور اسے ایک اخذ شدہ کلاس تفویض کرتے ہیں۔ اس معاملے میں یاد رکھنے کا اہم نکتہ یہ ہے کہ ہم پیرنٹ کلاس کو بازیافت کرنے کے لئے ایک پوائنٹر کا استعمال کرتے ہیں۔ جب یہ پیرنٹ کلاس کے اندر جاتا ہے تو یہ پیرنٹ کلاس کنسٹرکٹر کو چلاتا ہے۔ پھر، یہ چائلڈ کلاس میں جاتا ہے اور اپنے کنسٹرکٹر کو چلاتا ہے۔ چائلڈ کلاس کے تباہ کن کو پھانسی دینے سے پہلے، اسے پیرنٹ کلاس کے تباہ کن کو پھانسی دینا ہوگی۔ کمپائلر پیرنٹ کلاس کے ڈسٹرکٹر کو چلاتا ہے اور چائلڈ کلاس کے ڈسٹرکٹر کو عمل میں لائے بغیر کلاس کو ختم کر دیتا ہے۔ یہی مسئلہ ہے؛ یہ بچے کی کلاس کی یادداشت کو آزاد نہیں کرتا ہے۔ یہ پیرنٹ کلاس کے کنسٹرکٹر، چائلڈ کلاس کے کنسٹرکٹر، اور پیرنٹ کلاس کے ڈسٹرکٹر کی نمائندگی کرتا ہے۔ اس سے پتہ چلتا ہے کہ بچوں کی کلاس کو تباہ کرنے والے کو پھانسی نہیں دی جاتی ہے۔ اس عمل کے بعد، ہم مین() فنکشن میں پوائنٹر کو حذف کر دیتے ہیں۔

آؤٹ پٹ:

ورچوئل ڈسٹرکٹر کے ساتھ C++ مثال

آئیے ایک سادہ کوڈ کے ساتھ ورچوئل ڈسٹرکٹر پر بات کرتے ہیں تاکہ یہ فرق کیا جا سکے کہ یہ ورچوئل ڈسٹرکٹر کے ساتھ اور اس کے بغیر کیسے کام کرتا ہے۔

کوڈ:

# شامل کریں

نام کی جگہ کا استعمال کرتے ہوئے std ;
کلاس Parent_Class0
{
عوام :
پیرنٹ_کلاس0 ( )
{ cout << 'پیرنٹ کلاس کنسٹرکٹر' << endl ; }
ورچوئل ~Parent_Class0 ( )
{ cout << 'پیرنٹ کلاس ڈسٹرکٹر' << endl ; }
} ;
کلاس چائلڈ_1 : عوامی والدین_کلاس0
{
عوام :
بچہ_1 ( )
{ cout << 'چائلڈ کلاس کنسٹرکٹر' << endl ; }
ورچوئل ~بچہ_1 ( )
{ cout << 'چائلڈ کلاس ڈسٹرکٹر' << endl ; }
} ;
int مرکزی ( )
{
پیرنٹ_کلاس0 * پوائنٹر = نیا بچہ_1 ( ) ;
پوائنٹر کو حذف کریں ;
واپسی 0 ;
}

پہلے پروگرام نے اس مسئلے کی وضاحت کی جس کا ہم بغیر ورچوئل ڈسٹرکٹر کے سامنا کر رہے ہیں۔ اب، یہ کوڈ ورچوئل ڈسٹرکٹر کا استعمال کرتے ہوئے اس مسئلے کو حل کرے گا۔ سب سے پہلے، پہلا کوڈ کاپی کریں اور اس پروگرام میں دو جگہوں پر صرف ایک کلیدی لفظ شامل کریں۔ یہ لفظ 'مجازی' ہے۔ اس لفظ کو پیرنٹ کلاس کے ڈسٹرکٹر کے ساتھ داخل کریں، 'Parent_Class0'۔ اسی طرح چائلڈ کلاس کے ڈسٹرکٹر کے ساتھ اس کا ذکر کریں جو کہ 'Child_1' ہے جو پیرنٹ کلاس سے اخذ کیا گیا ہے۔ یہ 'ورچوئل' کلیدی لفظ تھوڑی سی تبدیلی کرتا ہے اور یہ 'Child_1' چائلڈ کلاس کے تباہ کن کو پہلے انجام دیتا ہے۔ پھر، یہ پیرنٹ کلاس، 'Parent_Class0' کے تباہ کن کو انجام دیتا ہے۔ باقی پروگرام ویسا ہی چلتا ہے جیسا کہ یہ ورچوئل ڈسٹرکٹر کے بغیر چلتا ہے۔ کوڈ کے اس چھوٹے سے ٹکڑے کو شامل کرکے، ہم اپنی یادداشت کو لیک ہونے سے بچا سکتے ہیں۔ اب، یہ کنسول پر چار پیغامات دکھاتا ہے۔ پہلے، پیرنٹ کلاس کا کنسٹرکٹر، پھر چائلڈ کلاس کا کنسٹرکٹر، چائلڈ کلاس کا ڈسٹرکٹر، اور پیرنٹ کلاس کا ڈسٹرکٹر۔ آخر میں، ہم مین() طریقہ کے اندر پوائنٹر کو حذف کر دیتے ہیں۔

آؤٹ پٹ:

C++ خالص ورچوئل ڈسٹرکٹر کی مثال

اس کوڈ میں، ہم خالص ورچوئل ڈسٹرکٹر کے بارے میں بات کریں گے، یہ کیسے کام کرتا ہے، اور یہ ورچوئل ڈسٹرکٹر سے کیسے مختلف ہے۔

کوڈ:

# شامل کریں

کلاس والدین_0 {
عوام :
ورچوئل ~والدین_0 ( ) = 0 ;
} ;
والدین_0 :: ~والدین_0 ( )
{
std :: cout << 'ہیلو میں خالص تباہ کن ہوں. آپ نے مجھے بلایا!' ;
}
کلاس چائلڈ_0 : عوامی والدین_0 {
عوام :
~بچہ_0 ( ) { std :: cout << 'ماخوذ ڈسٹرکٹر یہاں ہے۔ \n ' ; }
} ;

int مرکزی ( )
{
والدین_0 * ptr_0 = نیا بچہ_0 ( ) ;
ptr_0 کو حذف کریں۔ ;
واپسی 0 ;
}

پیرنٹ کلاس 'Parent_0' کوڈ کے پہلے مرحلے میں بنایا گیا ہے۔ اس کے اندر، ورچوئل پیرنٹ ڈسٹرکٹر بنائیں اور اسے 0 کے ساتھ تفویض کریں۔ یہ ورچوئل ڈسٹرکٹر کو خالص ورچوئل ڈسٹرکٹر پر سیٹ کرتا ہے جس کا مطلب ہے کہ پیرنٹ کلاس اب خلاصہ ہے اور ہم اس کلاس کی مثالیں نہیں بنا سکتے۔ پیرنٹ کلاس 'Parent_0' کے باہر، destructors اور std::cout کی وضاحت کریں۔ مطلوبہ متن کو std::cout استعمال کرکے دکھایا گیا ہے۔ پھر، پیرنٹ کلاس سے 'Child_0' کلاس اخذ کریں اور اس کے ڈسٹریکٹر کی وضاحت کریں۔ ڈسٹریکٹر کے اندر، ایک پیغام پرنٹ کریں۔ مین () فنکشن میں، پیرنٹ کلاس کا پوائنٹر بنائیں اور چائلڈ کلاس کو اس میں تفویض کریں۔

کمپائلر پیرنٹ کلاس 'Parent_0' میں جاتا ہے۔ جب پوائنٹر بن جاتا ہے، تو اس کا کنسٹرکٹر خود بخود بلایا جاتا ہے۔ پھر، کمپائلر اپنے کنسٹرکٹر کو طلب کرنے کے لیے چائلڈ کلاس میں جاتا ہے۔ کنسٹرکٹر کے کامیاب عمل کے بعد، یہ چائلڈ کلاس 'Child_0' کے تباہ کن کو انجام دیتا ہے۔ پھر، یہ پیرنٹ کلاس کے تباہ کن کو انجام دیتا ہے۔ اس طرح، ہم ایک خالص ورچوئل ڈسٹرکٹر بنا سکتے ہیں۔ اس کو استعمال کرنے کی ترغیب نہیں دی جاتی کیونکہ اس طریقہ کو استعمال کرنے سے والدین کا طبقہ خلاصہ بن جاتا ہے جو اسے بیکار بنا دیتا ہے۔ طریقہ کار جو زیادہ تر استعمال ہوتا ہے وہ ورچوئل ڈسٹرکٹر ہے اور یہ ایک اچھا عمل ہے۔

آؤٹ پٹ:

نتیجہ

ہم نے ورچوئل ڈسٹرکٹر کے بارے میں سیکھا جو OOP کے تصور سے شروع ہو کر کنسٹرکٹرز اور ڈسٹرکٹرز کی طرف بڑھتا ہے۔ ان سب کی وضاحت کے بعد، ہم نے کوڈنگ مثالوں اور خالص ورچوئل ڈسٹرکٹر کے ساتھ تفصیل سے ورچوئل ڈسٹرکٹر کے بارے میں بات کی۔ ورچوئل ڈسٹرکٹر کی وضاحت کرنے سے پہلے، ہمیں کنسٹرکٹرز، ڈسٹرکٹرز اور وراثت کے بارے میں جاننا چاہیے۔ وراثت میں، ہم والدین کی کلاس سے وراثت میں آتے ہیں۔ بچوں کی کلاسیں ایک سے زیادہ ہو سکتی ہیں لیکن والدین کی کلاس صرف ایک ہے۔ ورچوئل ڈسٹرکٹرز اور خالص ورچوئل ڈسٹرکٹرز کو میموری کے رساو سے بچانے کے لیے وراثت میں لاگو کیا جاتا ہے۔ بنیادی مثال سے لے کر جدید مثال تک، ہم نے ہر وہ چیز کا احاطہ کیا جو آپ کو استعمال کرنا شروع کرنے کے لیے جاننا چاہیے اور اخذ کردہ کلاس کی یادداشت کو عملی طور پر تباہ کر دیا ہے۔