انتقل إلى المحتوى

التحويل في c++

من ويكيبيديا، الموسوعة الحرة

تحويل الأنواع في سي بلس بلس : (بالإنجليزية: type casting)‏ وهي عبارة عن مجموعة طرق للتحويل من نوع إلى نوع معين في لغة ++C , مثلها مثل أي لغة أخرى , وبما أن لغة ++C لغة مميزة عن غيرها فلها طرق تحويل خاصة بها ,ويجب عليك كمبرمج لغة ++C أن تعرف كيف تتعامل مع هذه التحويلات بدقة لكي لا تكون برامجك عرضة للأخطاء التي أحيانا قد لاتكتشفها أثناء كتابة برنامجك .[1]

التحويل الضمني

[عدل]

التحويل الضمني (بالإنجليزية: Implicit conversion)‏ لايتطلب أي معامل , ويتم تنفيذها تلقائيا عندما يتم نسخ قيمة من نوع معين إلى نوع آخر موافق .


short s = 1000;
int a;
a = s;

هنا القيمة تم ترقيتها من short إلى int ,مع أننا لم نفوم باستخدام أي معامل للتحويل type_casting , هذا التحويل يسمى بالتحويل القياسي Implicit conversion ,وهو يؤثر في الأنواع الأساسية للبيانات , مثل تحويل الأنواع العديّدة (short to int, int to float, double to int) ويمكن تحويلهم أيضا إلى النوع المنطقي bool . مع ذلك هذه التحويلات تعد غير دقيقة أي يمكن أحيانا أن يطلق المترجم رسائل تحذيرية ,ولتجنب ذلك يجب أن نستخدم التحوي الصريح explicit conversion .

أيضا يمكن أن يتضمن التحويل الضمني التحويل بين مشيدات الفئات (classes) إذا كان في إحد مشيد الفئة كائن للفئة الأخرى , مثال على ذلك :


class A {};
class B { public: B (A a) {} };

A a;
B b = a;

في الكود السابق حدث تحويل بين كائنين A , B لأن مشيد الفئة B تحتوي على بارمتر من نوع A .لذلك التحويل الضمني مسموح فقط من A إلى B.

التحويل الصريح

[عدل]

(بالإنجليزية: Explicit conversion)‏ العديد من التحويلات , خاصة تلك التي تعبر عن تفسيرات مختلفة في القيمة ,مثل هذه التحويلات تحتاج إلى تحويل صريح . يوجد نمطين للتحويل الصريح هو الوظيفي (الدالي) functional وc-like :


short s = 1000;
int a;
a = (int) s; // c-like cast notation
a = int(s); // functional notation

معاملات التحويل الصريح يمكن استخدامها لمعظم أنواع البيانات الأساسية , ولكن يمكن أن تطبق بشكل عشوائي على الكائنات ومؤشرات الكائنات ,أي يمكن أن تكون صحيحة من حيث التركيب ولكن تسبب في حدوث خطأ وقت التشغيل run-time :


class A
{
    float x,y;
};
class B
{
    int i,j;
public:
    B (int a, int b) { i = a; j = b; }
    int result() { return i + j; }

};
int main()
{
    A d;
    B *b;
    b = (B) &d;      //Error
    cout <<b->result();
    return 0;
}

هذا الكود يقوم بتصريح مؤشر إلى الكائن B ,وبعد ذلك يسند له مرجع من كائن آخر A غير متوافق معه بالنوع :


b = (B) &d;

التحويل الصريح التقليدي يمكن أن يحول أي مؤشر إلى مؤشر آخر , ولكن بصرف النظر عن ذلك . إن استدعاء الدالة result قد تعطي خطأ في وقت التشغيل أو أنها تعطي قيمة غير متوقعة ,لأجل السطيرة على هذه التحويلات التي تتم بين الفئات ,لدينا أربع معاملات :

dynamic_cast وreinterpret_cast وstatic_cast وconst_cast

لديها صيغة خاصة فيها ,فيتم تمرير النوع داخل أقواس الزاوية <> ,وبعدها مباشرة يتم كتابة التعبير المراد تحويله بين قوسين .


dynamic_cast <new_type> (expression)

reinterpret_cast <new_type> (expression)

static_cast <new_type> (expression)

const_cast <new_type> (expression)

أما التحويل الصريح فأن صيغته كالتالي :


(new_type) expression

new_type (expression)

وكل نوع من أنواع التحويل لديها مايميزها عن الآخر .

التحويل الديناميكي

[عدل]

(بالإنجليزية: dynamic_cast)‏ يمكن أن يستخدم التحويل الديناميكي فقط مع المؤشرات والمراجع إلتي تشير إلى الكائنات Object , الغرض منه هو ضمان أن تكون نتيجة التحويل صالحة وصحيحة بالنسبة للفئة المطلوبة ,ولذلك dynamic_cast دائما تعطيك نتيجة صحيحة عندما تريد التحويل بين الفئة المشتقة إلى واحدة من الفئات الأساسية.


class CBase { };
class CDerived: public CBase { };

CBase b; CBase* pb;
CDerived d; CDerived* pd;

pb = dynamic_cast<CBase*>(&d); // ok: derived-to-base
pd = dynamic_cast<CDerived*>(&b); // wrong: base-to-derived

في الكود السابق ينتج المترجم خطأ بسبب التحويل الثاني لأن التحويل من فئة أساسية إلى فئة مشتقة غير مسموح . إلا إذا كانت الفئة متعددة الأشكال (نمط من أنماط oop). عندما تكون الفئة متعددة الأشكال polymorphic , فإن Dynamic_cast يقوم بحفص دقيق خلال وقت التشغيل للتأكد بأن القيمة المعادة صحيحة وصالحة للفئة المطلوبة ,مثال على ذلك :


// dynamic_cast
#include <iostream>
#include <exception>
using namespace std;

class CBase { virtual void dummy() {} };
class CDerived: public CBase { int a; };

int main () {
  try {
    CBase * pba = new CDerived;
    CBase * pbb = new CBase;
    CDerived * pd;

    pd = dynamic_cast<CDerived*>(pba);
    if (pd==0) cout <<"Null pointer on first type-cast" <<endl;

    pd = dynamic_cast<CDerived*>(pbb);
    if (pd==0) cout <<"Null pointer on second type-cast" <<endl;

  } catch (exception& e) {cout <<"Exception: " <<e.what();}
  return 0;
}

النتائج :


Null pointer on second type-cast

انظر أيضًا

[عدل]

مراجع

[عدل]
  1. ^ Computer Science With C++ Programming - Class Xi (بالإنجليزية). Allied Publishers. ISBN:978-81-7023-959-8. Archived from the original on 2020-07-01.
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy