Virtual Destructor بلغة C ++

Virtual Destructor Blght C



C ++ هي اللغة المستخدمة لإعطاء أساس للمفهوم الأساسي للبرمجة وتجعل التفكير المنطقي للمبرمجين قويًا. في C ++ ، يلعب OOP دورًا حيويًا نظرًا لأن OOP هي لغة موجهة للكائنات تنشئ كائنات من الفصول الدراسية. في OOP ، ندرس الفئات والأشياء. تحتوي الفئات على أعضاء البيانات الذين هم متغيرات من أنواع مختلفة ووظائف أعضاء مختلفة. بمساعدة الحالات ، نصل إلى بيانات أي فئة. كل فئة لها مُنشئها ومُدمِّرها عندما تقوم بإنشاء الفصل. يُطلق على المُنشئ نفسه عندما يتم إنشاء كائن تلك الفئة. يمكننا أيضًا تهيئة متغيرات فئة داخل المُنشئ. يتم أيضًا إنشاء المدمرات تلقائيًا باستخدام المُنشئ ولكن المدمرات تدمر الكائن وهي الوظيفة الأخيرة التي يتم استدعاؤها قبل تدمير الكائن. يتم إنشاء اسم الفصل ، على سبيل المثال فئة 'المهنة'. مُنشئها هو Profession () والمدمر هو ~ Profession (). الثلاثة منهم لديهم نفس الاسم.

بعد الحديث عن OOP والمنشئين والمدمرين ، دعنا نتحدث الآن عن المدمرات الافتراضية. المدمرات الافتراضية ، كما يحددها الاسم ، تدمر الكائن. لدينا فئة أساسية وفئة مشتقة مشتقة من الفئة الأساسية. كلا الفئتين لهما صانعيهما ومدمروهما. يقوم برنامج التدمير الظاهري بتحرير الذكريات التي يتم تخصيصها من خلال كائن الفئة المشتق أثناء حذف كائنات الفئة المشتقة باستخدام مؤشر الفئة الأساسية باستخدام الكلمة الأساسية 'الظاهرية'.

لماذا نستخدم المدمر الافتراضي؟

عند الانتهاء من تنفيذ وظائف أعضاء الفئة أو أوشك تنفيذ الطريقة main () على الانتهاء ، يتم استدعاء أداة التدمير تلقائيًا لتحرير الذاكرة التي تم تخصيصها أثناء إنشاء الكائن. الآن ، لماذا نستخدم المدمر الافتراضي؟ عند حذف الفئة الأساسية التي تشير إلى الفئة المشتقة ، يتم استخدام المؤشر (*) هنا. يتم استدعاء مدمر الفئة الأساسية فقط أثناء هذه العملية. لا يسمى مدمر الطبقة المشتق مما يؤدي إلى مشاكل. واحد منهم هو مشكلة تسرب الذاكرة. لتجنب هذه المشكلة وجعل الكود الخاص بنا آمنًا ، فإننا ندمر الكائنات فعليًا لتحرير مساحة الذاكرة التي تم تخصيصها أثناء إنشاء الكائنات عن طريق حذف مدمر الفئة الأساسية.

مثال أساسي C ++ بدون Virtual Destructor

دعونا نرى كيف يعمل البرنامج بدون أداة تدمير افتراضية باستخدام برنامج بسيط يقوم بحذف المؤشر.

الشفرة:

# تضمين

استخدام اسم للمحطة ؛
فئة Parent_Class0
{
عام :
Parent_Class0 ( )
{ كوت << 'منشئ فئة الأصل' << إندل ؛ }
~ Parent_Class0 ( )
{ كوت << 'مدمر فئة الأصل' << إندل ؛ }
} ؛
فئة Child_1 : Parent_Class0 العامة
{
عام :
طفل_1 ( )
{ كوت << 'منشئ فئة الطفل' << إندل ؛ }
~ طفل_1 ( )
{ كوت << 'مدمر فئة الأطفال' << إندل ؛ }
} ؛
int رئيسي ( )
{
Parent_Class0 * المؤشر = طفل جديد_1 ( ) ؛
مؤشر الحذف ؛
إرجاع 0 ؛
}

يشرح هذا الرمز كيفية تنفيذ الكود بدون مدمر افتراضي. بادئ ذي بدء ، قم بإنشاء فئة باسم 'Parent_Class0' والتي ستكون الفئة الأصلية. داخل هذه الفئة ، قم بإنشاء منشئ ومدمر. كما نعلم ، تتم تسمية المُنشئ والمُلحق بنفس اسم الفئة. يتم تمثيل المدمر بشكل مشابه للمُنشئ ولكن له رمز (~) يميزه عن المُنشئ. داخل المنشئ والمدمر ، اطبع رسالة باستخدام 'cout <<'. الآن ، قم بإنشاء فصل آخر وهو 'Child_1'. هذه الفئة مشتقة من الصنف الأصل ، 'Parent_Class0'. تحتوي الفئة المشتقة على مُنشئها ومُدمِّرها الذي يحتوي على رسالة للطباعة على شاشة الإخراج.

في طريقة main () ، ننشئ مثيلًا لـ 'Parent_Class0' ونخصص فئة مشتقة إليه. النقطة الحاسمة التي يجب تذكرها في هذه الحالة هي أننا نستخدم مؤشرًا لاسترداد الفئة الرئيسية. عندما ينتقل إلى داخل الفئة الأصل ، فإنه ينفذ مُنشئ الفئة الأصل. بعد ذلك ، ينتقل إلى الفصل الدراسي وينفذ منشئه. قبل تنفيذ أداة التدمير الخاصة بالفئة الفرعية ، يجب عليها تنفيذ أداة التدمير الخاصة بالفئة الأم. يقوم المترجم بتنفيذ مدمر الفئة الأصل وإنهاء الفئة دون تنفيذ مدمر الفئة الفرعية. هذه هي المشكلة؛ لا يحرر ذاكرة صف الطفل. إنه يمثل مُنشئ فئة أصل ، مُنشئ فئة فرعية ، ومُنشئ فئة أصل. هذا يدل على أنه لم يتم تنفيذ المدمر للفئة الفرعية. بعد هذا التنفيذ ، نحذف المؤشر في الدالة main ().

انتاج:

مثال C ++ مع Virtual Destructor

دعنا نناقش أداة التدمير الافتراضية برمز بسيط للتمييز بين كيفية عملها باستخدام أداة التدمير الافتراضية وبدونها.

الشفرة:

# تضمين

استخدام اسم للمحطة ؛
فئة Parent_Class0
{
عام :
Parent_Class0 ( )
{ كوت << 'منشئ فئة الأصل' << إندل ؛ }
ظاهري ~ Parent_Class0 ( )
{ كوت << 'مدمر فئة الأصل' << إندل ؛ }
} ؛
فئة Child_1 : Parent_Class0 العامة
{
عام :
طفل_1 ( )
{ كوت << 'منشئ فئة الطفل' << إندل ؛ }
افتراضي ~ Child_1 ( )
{ كوت << 'مدمر فئة الأطفال' << إندل ؛ }
} ؛
int رئيسي ( )
{
Parent_Class0 * المؤشر = طفل جديد_1 ( ) ؛
مؤشر الحذف ؛
إرجاع 0 ؛
}

شرح البرنامج الأول المشكلة التي نواجهها بدون مدمر افتراضي. الآن ، سيحل هذا الرمز هذه المشكلة باستخدام أداة تدمير افتراضية. أولاً ، انسخ الكود الأول وأضف كلمة رئيسية واحدة في مكانين في هذا البرنامج. هذه الكلمة هي 'افتراضية'. أدخل هذه الكلمة مع المدمر للفئة الأصل ، 'Parent_Class0'. وبالمثل ، اذكر هذا مع أداة تدمير الفئة الفرعية وهي 'Child_1' المشتقة من الفئة الأصلية. هذه الكلمة الأساسية 'الافتراضية' تُحدث تغييراً طفيفاً وتنفذ أداة تدمير الفئة الفرعية 'Child_1' أولاً. بعد ذلك ، يقوم بتنفيذ المدمر للفئة الأصل ، 'Parent_Class0'. يعمل باقي البرنامج بنفس الطريقة التي يعمل بها بدون مدمر افتراضي. بإضافة هذا الجزء الصغير من الكود ، يمكننا حفظ ذاكرتنا من التسرب. الآن ، يعرض أربع رسائل على وحدة التحكم. أولاً ، مُنشئ فئة أصل ، ثم مُنشئ فئة فرعية ، ومُدمِّر فئة فرعية ، ومُدمِّر فئة أصل. في النهاية ، نحذف المؤشر داخل طريقة main ().

انتاج:

C ++ مثال على Pure Virtual Destructor

في هذا الكود ، سنتحدث عن المدمر الافتراضي الخالص ، وكيف يعمل ، وكيف يختلف عن المدمر الافتراضي.

الشفرة:

# تضمين

فئة Parent_0 {
عام :
ظاهري ~ Parent_0 ( ) = 0 ؛
} ؛
الوالد_0 :: ~ Parent_0 ( )
{
الأمراض المنقولة جنسيا :: كوت << 'مرحبًا أنا محض مدمر. لقد اتصلت بي!' ؛
}
فئة Child_0 : Parent_0 العامة {
عام :
~ طفل_0 ( ) { الأمراض المنقولة جنسيا :: كوت << 'المدمر المشتق موجود هنا ' ؛ }
} ؛

int رئيسي ( )
{
الوالد_0 * ptr_0 = جديد Child_0 ( ) ؛
حذف ptr_0 ؛
إرجاع 0 ؛
}

يتم إنشاء الفئة الأصل 'Parent_0' في الخطوة الأولى من الكود. بداخله ، أنشئ أداة التدمير الأصلية الافتراضية وقم بتعيينها بـ 0. هذا يعين أداة التدمير الافتراضية إلى أداة تدمير افتراضية خالصة مما يعني أن الفئة الأصلية هي الآن مجردة ولا يمكننا إنشاء مثيلات هذه الفئة. خارج الفئة الأصلية 'Parent_0' ، حدد المدمرات و std :: cout. يتم عرض النص المطلوب باستخدام std :: cout. ثم اشتق فئة 'Child_0' من الفئة الأصلية وحدد أداة التدمير الخاصة بها. داخل المدمر ، اطبع رسالة. في الدالة main () ، أنشئ مؤشر الفئة الأصلية وعيِّن الفئة الفرعية لها.

ينتقل المترجم إلى الفئة الأصل 'Parent_0'. عندما يتم إنشاء المؤشر ، يتم استدعاء مُنشئه تلقائيًا. بعد ذلك ، ينتقل المترجم إلى الفئة الفرعية لاستدعاء المُنشئ الخاص به. بعد التنفيذ الناجح للمُنشئ ، فإنه ينفذ أداة تدمير الفئة الفرعية 'Child_0'. بعد ذلك ، يقوم بتنفيذ المدمر للفئة الأصل. بهذه الطريقة ، يمكننا صنع مدمر افتراضي خالص. لا يتم تشجيعها على استخدامها لأنه من خلال استخدام هذه الطريقة ، تصبح الطبقة الأصلية مجردة مما يجعلها عديمة الفائدة. المنهجية المستخدمة في الغالب هي أداة التدمير الافتراضية وهي ممارسة جيدة.

انتاج:

استنتاج

لقد تعلمنا عن المدمر الافتراضي بدءًا من مفهوم OOP إلى الانتقال نحو المنشئين والمدمرين. بعد شرح كل ذلك ، ناقشنا بالتفصيل عن المدمر الافتراضي مع أمثلة الترميز والمدمِّر الافتراضي الخالص. قبل شرح أداة التدمير الافتراضية ، يجب أن نعرف المنشئات والمدمرين والميراث. في الميراث ، نرث الفئات من فئة الأصل. يمكن أن تكون الفصول الفرعية أكثر من فصل ولكن الفصل الرئيسي واحد فقط. يتم تطبيق المدمرات الافتراضية والمدمرات الافتراضية البحتة في الوراثة للحفظ من تسرب الذاكرة. من المثال الأساسي إلى المثال المتقدم ، قمنا بتغطية كل ما يجب أن تعرفه للبدء في استخدام وتدمير ذاكرة الفئة المشتقة تقريبًا.