C++ এ ভার্চুয়াল ডেস্ট্রাক্টর

C E Bharcuyala Destraktara



C++ হল সেই ভাষা যা প্রোগ্রামিং এর মৌলিক ধারণার ভিত্তি প্রদান করতে এবং প্রোগ্রামারদের যৌক্তিক চিন্তাকে শক্তিশালী করে তোলে। C++ এ, OOP একটি গুরুত্বপূর্ণ ভূমিকা পালন করে যেহেতু OOP হল একটি অবজেক্ট ওরিয়েন্টেড ভাষা যা ক্লাসের অবজেক্ট তৈরি করে। OOP-তে, আমরা ক্লাস এবং অবজেক্ট অধ্যয়ন করি। ক্লাসে ডাটা মেম্বার থাকে যেগুলো বিভিন্ন ধরনের এবং বিভিন্ন মেম্বার ফাংশনের ভেরিয়েবল। দৃষ্টান্তের সাহায্যে, আমরা যেকোনো শ্রেণীর ডেটা অ্যাক্সেস করি। আপনি যখন ক্লাস তৈরি করেন তখন প্রতিটি ক্লাসের তার কনস্ট্রাক্টর এবং ডেস্ট্রাক্টর থাকে। কনস্ট্রাক্টরকে বলা হয় যখন সেই ক্লাসের অবজেক্ট তৈরি করা হয়। আমরা কন্সট্রাক্টরের ভিতরে একটি ক্লাসের ভেরিয়েবলও ইনিশিয়ালাইজ করতে পারি। কনস্ট্রাক্টরের সাথে ডিস্ট্রাক্টরও স্বয়ংক্রিয়ভাবে তৈরি হয় কিন্তু ডেস্ট্রাক্টররা বস্তুটিকে ধ্বংস করে এবং এটিই শেষ ফাংশন যা অবজেক্টকে ধ্বংস করার আগে বলা হয়। ক্লাসের নাম, উদাহরণস্বরূপ 'পেশা' ক্লাস তৈরি করা হয়েছে। এর কনস্ট্রাক্টর হল Profession() এবং Destructor হল ~Profession()। তাদের তিনজনের নাম একই।

ওওপি, কনস্ট্রাক্টর এবং ডেস্ট্রাক্টর সম্পর্কে কথা বলার পর, এখন ভার্চুয়াল ডেস্ট্রক্টর সম্পর্কে কথা বলা যাক। ভার্চুয়াল ডেস্ট্রাক্টর, নাম উল্লেখ করে, বস্তুটিকে ধ্বংস করে। আমাদের একটি বেস ক্লাস এবং একটি প্রাপ্ত শ্রেণী রয়েছে যা বেস ক্লাস থেকে উদ্ভূত। উভয় শ্রেণীরই তাদের নির্মাণকারী এবং ধ্বংসকারী রয়েছে। ভার্চুয়াল ডেস্ট্রাক্টর স্মারককে মুক্ত করে যা 'ভার্চুয়াল' কীওয়ার্ডের সাথে একটি বেস ক্লাস পয়েন্টার ব্যবহার করে উদ্ভূত ক্লাসের অবজেক্ট মুছে ফেলার সময় বরাদ্দ করা হয়।

কেন আমরা ভার্চুয়াল ধ্বংসকারী ব্যবহার করব?

যখন ক্লাস মেম্বার ফাংশনগুলি সম্পাদন করা হয় বা main() পদ্ধতির সম্পাদন শেষ হতে চলেছে, তখন অবজেক্ট তৈরির সময় বরাদ্দ করা মেমরিটি মুক্ত করতে ডেস্ট্রাক্টরকে স্বয়ংক্রিয়ভাবে কল করা হয়। এখন, কেন আমরা একটি ভার্চুয়াল ধ্বংসকারী ব্যবহার করব? যখন বেস ক্লাস মুছে ফেলা হয় যা প্রাপ্ত শ্রেণীকে নির্দেশ করে, এখানে পয়েন্টার (*) ব্যবহার করা হয়। বেস ক্লাস ডেস্ট্রাক্টর শুধুমাত্র এই প্রক্রিয়ার সময় বলা হয়। প্রাপ্ত বর্গ ধ্বংসকারী বলা হয় না যা সমস্যার দিকে নিয়ে যায়। তার মধ্যে একটি মেমরি লিকেজ সমস্যা। এই সমস্যাটি এড়াতে এবং আমাদের কোড সুরক্ষিত করতে, আমরা বেস ক্লাস ডেস্ট্রাক্টর মুছে অবজেক্ট তৈরির সময় বরাদ্দ করা মেমরি স্পেস খালি করার জন্য বস্তুগুলিকে কার্যত ধ্বংস করি।

ভার্চুয়াল ডেস্ট্রাক্টর ছাড়া C++ বেসিক উদাহরণ

আসুন দেখি কীভাবে প্রোগ্রামটি একটি ভার্চুয়াল ডেস্ট্রাক্টর ছাড়াই কাজ করে একটি সাধারণ প্রোগ্রাম যা পয়েন্টারটি মুছে দেয়।

কোড:

# অন্তর্ভুক্ত করুন

নামস্থান std ব্যবহার করে ;
ক্লাস Parent_Class0
{
সর্বজনীন :
অভিভাবক_ক্লাস0 ( )
{ cout << 'প্যারেন্ট ক্লাস কনস্ট্রাক্টর' << endl ; }
~প্যারেন্ট_ক্লাস0 ( )
{ cout << 'প্যারেন্ট ক্লাস ডিস্ট্রাক্টর' << endl ; }
} ;
ক্লাস চাইল্ড_1 : সর্বজনীন অভিভাবক_ক্লাস0
{
সর্বজনীন :
শিশু_1 ( )
{ cout << 'শিশু শ্রেণীর নির্মাতা' << endl ; }
~শিশু_১ ( )
{ cout << 'শিশু শ্রেণি ধ্বংসকারী' << endl ; }
} ;
int প্রধান ( )
{
অভিভাবক_ক্লাস0 * নির্দেশক = নতুন শিশু_1 ( ) ;
পয়েন্টার মুছুন ;
ফিরে 0 ;
}

এই কোডটি ব্যাখ্যা করে কিভাবে কোডটি ভার্চুয়াল ডেস্ট্রাক্টর ছাড়াই কার্যকর হয়। প্রথমত, 'Parent_Class0' নামে একটি ক্লাস তৈরি করুন যেটি হবে প্যারেন্ট ক্লাস। এই শ্রেণীর ভিতরে, একটি কনস্ট্রাক্টর এবং ডেস্ট্রাক্টর তৈরি করুন। আমরা জানি, কনস্ট্রাক্টর এবং ডেস্ট্রাক্টরের নাম ক্লাস হিসাবে একই। ধ্বংসকারীকে কনস্ট্রাক্টরের অনুরূপভাবে উপস্থাপন করা হয় তবে এটির একটি চিহ্ন (~) রয়েছে যা এটিকে কনস্ট্রাক্টর থেকে আলাদা করে। কনস্ট্রাক্টর এবং ডেস্ট্রক্টরের ভিতরে, 'cout<<' ব্যবহার করে একটি বার্তা প্রিন্ট করুন। এখন, আরেকটি ক্লাস তৈরি করুন যা হল 'Child_1'। এই ক্লাসটি প্যারেন্ট ক্লাস, 'Parent_Class0' থেকে নেওয়া হয়েছে। প্রাপ্ত বর্গটির কনস্ট্রাক্টর এবং ডেস্ট্রাক্টর রয়েছে যা আউটপুট স্ক্রিনে প্রিন্ট করার জন্য একটি বার্তা ধারণ করে।

main() পদ্ধতিতে, আমরা 'Parent_Class0' এর একটি উদাহরণ তৈরি করি এবং এটিতে একটি প্রাপ্ত ক্লাস বরাদ্দ করি। এই ক্ষেত্রে মনে রাখা গুরুত্বপূর্ণ পয়েন্ট হল যে আমরা প্যারেন্ট ক্লাস পুনরুদ্ধার করতে একটি পয়েন্টার ব্যবহার করি। যখন এটি প্যারেন্ট ক্লাসের ভিতরে যায়, তখন এটি প্যারেন্ট ক্লাস কনস্ট্রাক্টরকে এক্সিকিউট করে। তারপর, এটি চাইল্ড ক্লাসে যায় এবং এর কনস্ট্রাক্টরকে এক্সিকিউট করে। শিশু শ্রেণীর ধ্বংসকারীকে কার্যকর করার আগে, এটিকে অভিভাবক শ্রেণীর ধ্বংসকারীকে কার্যকর করতে হবে। কম্পাইলার প্যারেন্ট ক্লাসের ডেস্ট্রাক্টর এক্সিকিউট করে এবং চাইল্ড ক্লাসের ডেস্ট্রক্টর এক্সিকিউট না করেই ক্লাস শেষ করে। সেটাইতো সমস্যা; এটি শিশুর ক্লাসের স্মৃতিকে মুক্ত করে না। এটি একটি অভিভাবক শ্রেণীর কন্সট্রাকটর, একটি শিশু শ্রেণীর কনস্ট্রাক্টর এবং একটি অভিভাবক শ্রেণীর ধ্বংসকারীকে প্রতিনিধিত্ব করে। এটি দেখায় যে একটি শিশু শ্রেণীর ধ্বংসকারীকে মৃত্যুদণ্ড দেওয়া হয় না। এই এক্সিকিউশনের পরে, আমরা main() ফাংশনের পয়েন্টারটি মুছে ফেলি।

আউটপুট:

ভার্চুয়াল ডেস্ট্রাক্টরের সাথে C++ উদাহরণ

আসুন ভার্চুয়াল ডেস্ট্রক্টরের সাথে এবং ভার্চুয়াল ডেস্ট্রক্টর ছাড়া কীভাবে কাজ করে তা আলাদা করার জন্য একটি সাধারণ কোডের সাথে আলোচনা করা যাক।

কোড:

# অন্তর্ভুক্ত করুন

নামস্থান std ব্যবহার করে ;
ক্লাস Parent_Class0
{
সর্বজনীন :
অভিভাবক_ক্লাস0 ( )
{ cout << 'প্যারেন্ট ক্লাস কনস্ট্রাক্টর' << endl ; }
ভার্চুয়াল ~Parent_Class0 ( )
{ cout << 'প্যারেন্ট ক্লাস ডিস্ট্রাক্টর' << endl ; }
} ;
ক্লাস চাইল্ড_1 : সর্বজনীন অভিভাবক_ক্লাস0
{
সর্বজনীন :
শিশু_1 ( )
{ cout << 'শিশু শ্রেণীর নির্মাতা' << endl ; }
ভার্চুয়াল ~Child_1 ( )
{ cout << 'শিশু শ্রেণি ধ্বংসকারী' << endl ; }
} ;
int প্রধান ( )
{
অভিভাবক_ক্লাস0 * নির্দেশক = নতুন শিশু_1 ( ) ;
পয়েন্টার মুছুন ;
ফিরে 0 ;
}

ভার্চুয়াল ডেস্ট্রাক্টর ছাড়াই আমরা যে সমস্যার মুখোমুখি হচ্ছি তা প্রথম প্রোগ্রামটি ব্যাখ্যা করেছে। এখন, এই কোডটি একটি ভার্চুয়াল ডেস্ট্রাক্টর ব্যবহার করে সেই সমস্যার সমাধান করবে। প্রথমে, প্রথম কোডটি অনুলিপি করুন এবং এই প্রোগ্রামে দুটি জায়গায় শুধু একটি কীওয়ার্ড যোগ করুন। এই শব্দটি 'ভার্চুয়াল'। প্যারেন্ট ক্লাস, 'Parent_Class0' এর ধ্বংসকারীর সাথে এই শব্দটি সন্নিবেশ করুন। একইভাবে, শিশু শ্রেণীর ধ্বংসকারীর সাথে এটি উল্লেখ করুন যা 'Child_1' যা পিতামাতার শ্রেণী থেকে উদ্ভূত। এই 'ভার্চুয়াল' কীওয়ার্ডটি একটু পরিবর্তন করে এবং এটি প্রথমে 'Child_1' চাইল্ড ক্লাসের ধ্বংসকারীকে কার্যকর করে। তারপর, এটি প্যারেন্ট ক্লাস, 'Parent_Class0' এর ধ্বংসকারীকে কার্যকর করে। ভার্চুয়াল ডেস্ট্রাক্টর ছাড়াই প্রোগ্রামের বাকি কাজগুলো একইভাবে কাজ করে। কোডের এই ছোট্ট অংশটি যোগ করে, আমরা আমাদের মেমরিকে ফুটো থেকে বাঁচাতে পারি। এখন, এটি কনসোলে চারটি বার্তা প্রদর্শন করে। প্রথমত, একটি অভিভাবক শ্রেণীর নির্মাণকারী, তারপর একটি শিশু শ্রেণীর নির্মাণকারী, একটি শিশু শ্রেণীর ধ্বংসকারী, এবং একটি অভিভাবক শ্রেণীর ধ্বংসকারী। শেষ পর্যন্ত, আমরা main() পদ্ধতির মধ্যে পয়েন্টার মুছে ফেলি।

আউটপুট:

বিশুদ্ধ ভার্চুয়াল ধ্বংসকারীর C++ উদাহরণ

এই কোডে, আমরা খাঁটি ভার্চুয়াল ডেস্ট্রক্টর সম্পর্কে কথা বলব, এটি কীভাবে কাজ করে এবং এটি ভার্চুয়াল ডেস্ট্রক্টর থেকে কীভাবে আলাদা।

কোড:

# অন্তর্ভুক্ত করুন

ক্লাস অভিভাবক_0 {
সর্বজনীন :
ভার্চুয়াল ~Parent_0 ( ) = 0 ;
} ;
অভিভাবক_0 :: ~পিতা_0 ( )
{
std :: cout << 'হ্যালো আমি বিশুদ্ধ ধ্বংসকারী। আপনি আমাকে ডেকেছেন!' ;
}
ক্লাস চাইল্ড_0 : সর্বজনীন অভিভাবক_0 {
সর্বজনীন :
~শিশু_০ ( ) { std :: cout << 'উত্পন্ন ধ্বংসকারী এখানে \n ' ; }
} ;

int প্রধান ( )
{
অভিভাবক_0 * ptr_0 = নতুন শিশু_0 ( ) ;
ptr_0 মুছুন ;
ফিরে 0 ;
}

কোডের প্রথম ধাপে প্যারেন্ট ক্লাস 'Parent_0' তৈরি করা হয়েছে। এটির ভিতরে, ভার্চুয়াল প্যারেন্ট ডেস্ট্রাক্টর তৈরি করুন এবং এটিকে 0 দিয়ে বরাদ্দ করুন। এটি ভার্চুয়াল ডেস্ট্রক্টরকে বিশুদ্ধ ভার্চুয়াল ডেস্ট্রাক্টরে সেট করে যার মানে হল যে প্যারেন্ট ক্লাসটি এখন বিমূর্ত এবং আমরা এই ক্লাসের উদাহরণ তৈরি করতে পারি না। প্যারেন্ট ক্লাস 'Parent_0' এর বাইরে, ধ্বংসকারী এবং std::cout সংজ্ঞায়িত করুন। প্রয়োজনীয় পাঠ্যটি std::cout ব্যবহার করে দেখানো হয়েছে। তারপরে, প্যারেন্ট ক্লাস থেকে একটি 'Child_0' ক্লাস বের করুন এবং এর ধ্বংসকারীকে সংজ্ঞায়িত করুন। ধ্বংসকারীর ভিতরে, একটি বার্তা প্রিন্ট করুন। main() ফাংশনে, প্যারেন্ট ক্লাসের পয়েন্টার তৈরি করুন এবং এতে চাইল্ড ক্লাস বরাদ্দ করুন।

কম্পাইলার প্যারেন্ট ক্লাস 'Parent_0' এ যায়। পয়েন্টার তৈরি হলে, এর কনস্ট্রাক্টর স্বয়ংক্রিয়ভাবে বলা হয়। তারপর, কম্পাইলার তার কনস্ট্রাক্টরকে ডাকতে চাইল্ড ক্লাসে যায়। কনস্ট্রাক্টর সফলভাবে কার্যকর করার পরে, এটি একটি শিশু শ্রেণীর 'Child_0' এর ধ্বংসকারীকে কার্যকর করে। তারপরে, এটি একটি অভিভাবক শ্রেণীর ধ্বংসকারীকে কার্যকর করে। এইভাবে, আমরা একটি বিশুদ্ধ ভার্চুয়াল ধ্বংসকারী তৈরি করতে পারি। এটি ব্যবহার করার জন্য উত্সাহিত করা হয় না কারণ এই পদ্ধতিটি ব্যবহার করে, অভিভাবক শ্রেণীটি বিমূর্ত হয়ে যায় যা এটিকে অকেজো করে তোলে। যে পদ্ধতিটি বেশিরভাগ ব্যবহৃত হয় তা হল ভার্চুয়াল ধ্বংসকারী এবং এটি একটি ভাল অনুশীলন।

আউটপুট:

উপসংহার

আমরা ভার্চুয়াল ডেস্ট্রক্টর সম্পর্কে শিখেছি OOP এর ধারণা থেকে শুরু করে কনস্ট্রাক্টর এবং ডেস্ট্রাক্টরের দিকে এগিয়ে যাওয়া। এই সমস্ত ব্যাখ্যা করার পরে, আমরা কোডিং উদাহরণ এবং বিশুদ্ধ ভার্চুয়াল ধ্বংসকারীর সাথে ভার্চুয়াল ডেস্ট্রক্টর সম্পর্কে বিস্তারিত আলোচনা করেছি। ভার্চুয়াল ডেস্ট্রক্টর ব্যাখ্যা করার আগে, আমাদের অবশ্যই কনস্ট্রাক্টর, ডেস্ট্রাক্টর এবং উত্তরাধিকার সম্পর্কে জানতে হবে। উত্তরাধিকারসূত্রে, আমরা একটি অভিভাবক শ্রেণীর থেকে ক্লাসগুলি উত্তরাধিকার সূত্রে পাই। শিশু ক্লাস একাধিক হতে পারে কিন্তু অভিভাবক শ্রেণী শুধুমাত্র একটি। ভার্চুয়াল ধ্বংসকারী এবং বিশুদ্ধ ভার্চুয়াল ধ্বংসকারী মেমরি লিকেজ থেকে বাঁচাতে উত্তরাধিকারে প্রয়োগ করা হয়। প্রাথমিক উদাহরণ থেকে শুরু করে উন্নত উদাহরণ পর্যন্ত, আমরা প্রাপ্ত ক্লাসের মেমরি ব্যবহার এবং কার্যত ধ্বংস করতে শুরু করার জন্য আপনার যা জানা উচিত তা আমরা কভার করেছি।