C++ ভার্চুয়াল কনস্ট্রাক্টর

C Bharcuyala Kanastraktara



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

যাইহোক, একটি ভার্চুয়াল ধ্বংসকারী বিদ্যমান থাকতে পারে। এখানে, আমরা C++ এ ভার্চুয়াল কনস্ট্রাক্টর তৈরি করার সাথে সাথে ভার্চুয়াল কনস্ট্রাক্টরের পরিবর্তে ভার্চুয়াল ডেস্ট্রক্টর তৈরি করলে কী ঘটে তা দেখাব।

উদাহরণ 1:

আসুন ভার্চুয়াল কনস্ট্রাক্টর তৈরি করি এবং 'iostream' হেডার ফাইলটি রেখে আমাদের কোড শুরু করি। এই হেডার ফাইলটি 'cin' এবং 'cout' এর মতো ফাংশনগুলির জন্য এটিতে ঘোষণা করা হয়েছে। এর পরে, আমরা 'std' নামস্থান যোগ করি, তাই আমরা আমাদের কোডের প্রতিটি ফাংশনের সাথে এই 'std' যোগ করতে পারি না। এর পরে, আমরা 'my_base' নামে একটি ক্লাস তৈরি করি যা আমাদের কোডের বেস ক্লাস এবং তারপর ভার্চুয়াল কনস্ট্রাক্টর তৈরি করতে 'পাবলিক' যোগ করুন।







ভার্চুয়াল কনস্ট্রাক্টর এখানে 'ভার্চুয়াল' কীওয়ার্ড বসিয়ে তৈরি করা হয়েছে। এই ভার্চুয়াল কনস্ট্রাক্টরের ভিতরে, আমরা একটি 'cout' স্টেটমেন্ট রাখি। এর নীচে, আমরা 'শো' নামে একটি ফাংশন তৈরি করি যেখানে আমরা আবার 'cout' ব্যবহার করি। এর পরে, আমরা 'my_derived' নামে এই বেস ক্লাসের একটি প্রাপ্ত ক্লাস তৈরি করি এবং তারপর 'পাবলিক' ক্ষেত্রে 'my_derived()' কনস্ট্রাক্টর স্থাপন করি। আমরা এই 'my_derived()' কনস্ট্রাক্টরে একটি 'cout' স্টেটমেন্ট সন্নিবেশ করি। এর নীচে, আমরা 'শো' নামে একটি ফাংশন তৈরি করি যেখানে আমরা আবার 'cout' ব্যবহার করি।



এখন, “main()” চালু করার পর, আমরা “my_ptr” নামের বেস ক্লাসের একটি পয়েন্টার তৈরি করি এবং ডেরাইভড ক্লাসের অবজেক্টও তৈরি করি যা হল “Obj_d”। এর পরে, আমরা 'My_ptr' কে 'Obj_d' এর ঠিকানা বরাদ্দ করি। তারপর, আমরা 'my_ptr' এর মাধ্যমে 'show()' ফাংশনকে কল করি।



কোড 1:





# অন্তর্ভুক্ত করুন
ব্যবহার নামস্থান std ;
ক্লাস আমার_বেস
{
সর্বজনীন :
অপার্থিব আমার_বেস ( )
{
cout << 'এখানে আমার বেস ক্লাস' << endl ;
}
অকার্যকর প্রদর্শন ( )
{
cout << 'বেস ক্লাসের শো ফাংশন' << endl ;
}
} ;
ক্লাস my_derived : সর্বজনীন আমার_বেস
{
সর্বজনীন :
my_derived ( )
{
cout << 'এখানে আমার প্রাপ্ত ক্লাস' << endl ;
}
অকার্যকর প্রদর্শন ( )
{
cout << 'উত্পন্ন শ্রেণীর শো ফাংশন' < প্রদর্শন ( ) ;
}

আউটপুট:
এখানে, এটি একটি ত্রুটি বার্তা দেখায় যা বলে যে কনস্ট্রাক্টরকে C++ প্রোগ্রামিং-এ ভার্চুয়াল ঘোষণা করা যাবে না। সুতরাং, আমরা দেখতে পাচ্ছি যে C++ আমাদের ভার্চুয়াল কনস্ট্রাক্টর তৈরি করতে দেয় না কিন্তু আমরা ভার্চুয়াল ডেস্ট্রক্টর তৈরি করতে পারি।



উদাহরণ 2:

চলুন আগের সমস্যার সমাধান করি এবং এই কোডে ভার্চুয়াল ডেস্ট্রাক্টর তৈরি করি। 'new_base' ক্লাস ঘোষণা করার পর, আমরা 'public' কন্সট্রাক্টর রাখি যেখানে আমরা 'new_base' এর সাথে 'ভার্চুয়াল ~' যোগ করে ভার্চুয়াল ডেস্ট্রাক্টর তৈরি করি। আমরা এই ভার্চুয়াল ধ্বংসকারীতে একটি 'cout' বিবৃতি সন্নিবেশ করি। এটির নীচে, আমরা 'শো' নামে একটি ফাংশন তৈরি করি যা 'cout' ব্যবহার করে। এর পরে, আমরা একটি derived ক্লাস তৈরি করি যা এই 'new_base' বেস ক্লাসের 'new_derived' এবং 'public' ক্ষেত্রে 'new_derived()'destructor তৈরি করি। এই 'new_derived()' ধ্বংসকারী এখন এটিতে একটি 'cout' বিবৃতি যোগ করেছে।

এর নীচে, আমরা 'শো' নামে একটি ফাংশন তৈরি করি যেটি আবার 'cout' স্টেটমেন্ট ব্যবহার করে। 'main()' ফাংশন কল করার পরে, আমরা এখন 'obj_d' প্রাপ্ত ক্লাসের একটি অবজেক্ট এবং সেই সাথে 'ptr1' নামে বেস ক্লাসের একটি পয়েন্টার তৈরি করি। এর পরে, আমরা 'ptr1' কে 'obj_d' ঠিকানা দিই। এর পরে, 'ptr1' ব্যবহার করে 'শো()' পদ্ধতিটি চালু করা হয়।

কোড 2:

# অন্তর্ভুক্ত করুন
ব্যবহার নামস্থান std ;
ক্লাস নতুন_বেস
{
সর্বজনীন :
অপার্থিব ~নতুন_বেস ( )
{
cout << 'বেস ক্লাস ধ্বংসকারী এখানে' << endl ;
}
অকার্যকর প্রদর্শন ( )
{
cout << 'বেস ক্লাসের শো ফাংশন' << endl ;
}
} ;
ক্লাস new_derived : সর্বজনীন নতুন_বেস
{
সর্বজনীন :
~ নতুন_প্রাপ্ত ( )
{
cout << 'উত্পন্ন শ্রেণী ধ্বংসকারী এখানে' << endl ;
}
অকার্যকর প্রদর্শন ( )
{
cout << 'বেস ক্লাসের শো ফাংশন' < প্রদর্শন ( ) ;
}

আউটপুট:
এই প্রোগ্রামটি 'new_base' এর একটি পয়েন্টার অবজেক্ট ব্যবহার করে যা 'obj_d' প্রাপ্ত ক্লাসের দিকে নির্দেশ করে। সুতরাং, এটি প্রথমে 'new_base' ক্লাসের 'show()' পদ্ধতিকে কল করে। তারপর, এটি 'new_derived' ক্লাসের '~new_derived()' পদ্ধতিকে কল করে এবং বেস ক্লাসের '~new_base' প্রদর্শন করে।

উদাহরণ 3:

'ভার্চুয়াল' কনস্ট্রাক্টর তৈরি করার জন্য এখানে আরেকটি কোড আছে। 'iostream' এবং 'std' নামস্থান অন্তর্ভুক্ত করার পরে, আমরা একটি শ্রেণী 'B' তৈরি করি। এর নীচে, আমরা 'পাবলিক' কনস্ট্রাক্টর তৈরি করি যা 'B()' এবং তারপর 'cout' তৈরি করি। কনস্ট্রাক্টর এবং ডেস্ট্রাক্টর ফাংশন একটি 'পাবলিক' অ্যাক্সেস স্পেসিফায়ার ব্যবহার করে সংজ্ঞায়িত করা হয় যেখানে ক্লাসের যেকোনো বস্তু কল করতে পারে।

এখন, আমরা এই বেস ক্লাসের “~B()” ডেস্ট্রাক্টরও তৈরি করি যেখানে আমরা আবার “cout” ব্যবহার করি। তারপর, আমরা 'D' ক্লাস তৈরি করি যা 'B' বেস ক্লাসের প্রাপ্ত ক্লাস এবং এখানে 'পাবলিক' রাখি। এই “পাবলিক”-এর ভিতরে, আমরা যথাক্রমে “D()” এবং “~D” নাম দিয়ে কন্সট্রাক্টর এবং সেইসাথে ডিরাইভড ক্লাসের ডেস্ট্রক্টর তৈরি করি। উভয়ই তাদের ভিতরে 'কাউট' ধারণ করে। এখন, আমাদের 'main()' ফাংশন আছে। এই ফাংশনটি কল করার পরে, আমরা বেস ক্লাসের পয়েন্টার অবজেক্ট তৈরি করি।

তারপর, আমরা 'delete' কীওয়ার্ড ব্যবহার করি এবং এখানে 'base_ptr' রাখি। এই ক্ষেত্রে, বেস ক্লাসের পয়েন্টার অবজেক্টকে কল করে ধ্বংসকারীর স্থান মুছে ফেলা হয়।

কোড 3:

#অন্তর্ভুক্ত করুন
ব্যবহার নামস্থান std ;
ক্লাস
{
সর্বজনীন :
( )
{
cout << 'বেস ক্লাসের কনস্ট্রাক্টর' << endl ;
}
~ খ ( )
{
cout << 'বেস ক্লাসের ধ্বংসকারী' << endl ;
}
} ;

ক্লাস ডি : সর্বজনীন
{
সর্বজনীন :
ডি ( )
{
cout << 'উত্পন্ন শ্রেণীর কনস্ট্রাক্টর' << endl ;
}
~ ডি ( )
{
cout << 'উত্পন্ন শ্রেণীর ধ্বংসকারী' << endl ;
}
} ;
int প্রধান ( )
{
* base_ptr = নতুন ডি ;
মুছে ফেলা base_ptr ;
}

আউটপুট:
ফলাফল দেখায় যে এটি একটি পয়েন্টার অবজেক্ট ব্যবহার করে যা প্রধান ফাংশনে 'B' শ্রেণীতে নির্দেশ করে। সুতরাং, এটি প্রথমে 'B' শ্রেণীর 'কন্সট্রাক্টর()' কে কল করে। তারপর, এটি 'ডি' ক্লাসের 'কনস্ট্রাক্টর()' কল করে। পয়েন্টার অবজেক্ট যা 'B' এবং 'D' ক্লাসের ধ্বংসকারীদের দ্বারা ধারণ করা হয় তা মুছে ফেলা হয়। প্রোগ্রামের মধ্যে 'D' ক্লাসের ধ্বংসকারীকে আহ্বান না করে, 'B' ক্লাস পয়েন্টার শুধুমাত্র 'B' শ্রেণীর ধ্বংসকারীকে সরিয়ে দেয়। ফলে প্রোগ্রামের মেমরি নষ্ট হয়ে যায়।

উপসংহার

আমরা C++ প্রোগ্রামিং-এ 'ভার্চুয়াল নির্মাণ' ধারণা নিয়ে আলোচনা করেছি। আমরা অনুসন্ধান করেছি যে আমরা C++ এ ভার্চুয়াল কনস্ট্রাক্টর তৈরি করতে পারি না, তবে আমরা আমাদের কোডগুলিতে ভার্চুয়াল ধ্বংসকারী তৈরি করতে পারি। এখানে, আমরা C++ প্রোগ্রামিং-এ ভার্চুয়াল কনস্ট্রাক্টর তৈরি করার সময় কী ঘটেছিল এবং আমাদের কোডে ভার্চুয়াল ডেস্ট্রক্টরের কাজগুলি দেখিয়েছি। আমরা শিখেছি যে কনস্ট্রাক্টর ভার্চুয়াল হতে পারে না, তবে আমরা আমাদের ক্লাসে ভার্চুয়াল ডেস্ট্রক্টর তৈরি করতে পারি। আমরা কিছু উদাহরণ দেখিয়েছি এবং এই নির্দেশিকায় এই কোডগুলিকে পুঙ্খানুপুঙ্খভাবে ব্যাখ্যা করেছি।