مرجع
آخر الزيارات

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

755 كلمة•0 مشاهدة•🗒️ منذ 12 يوماً
باختصار: تحويل الأنواع في سي بلس بلس : وهي عبارة عن مجموعة طرق للتحويل من نوع إلى نوع معين في لغة ++C , مثلها مثل أي لغة أخرى , وبما أن لغة ++C لغة مميزة عن غيرها فلها طرق تحويل خاصة بها ,ويجب عليك كمبرمج لغة ++C أن تعرف كيف تتعامل مع هذه التحويلات…. تجد هنا «pd = dynamic_cast(&b); // wrong: base-to-derived»، «using namespace std;» و«int i,j;» ضمن 18 قسماً.
المحتويات
  1. pd = dynamic_cast(&b); // wrong: base-to-derived
  2. using namespace std;
  3. int i,j;
  4. التحويل الضمني
  5. pd = dynamic_cast(pbb);
  6. b = (B) &d;
  7. dynamic_cast وreinterpret_cast وstatic_cast وconst_cast
  8. pd = dynamic_cast(pba);
  9. }
  10. B b = a;
  11. التحويل الديناميكي
  12. a = s;
  13. a = int(s); // functional notation
  14. (new_type) expression
  15. class A {};
  16. int a;
  17. }
  18. التحويل الصريح
التحويل في c++

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

pd = dynamic_cast(&b); // wrong: base-to-derived

وفي هذا الصدد، عندما تكون الفئة متعددة الأشكال polymorphic , فإن Dynamic_cast يقوم بحفص دقيق خلال وقت التشغيل للتأكد بأن القيمة المعادة صحيحة وصالحة للفئة المطلوبة ,مثال على ذلك :

  • // dynamic_cast
  • #include
  • #include

في هذا الإطار، في الكود السابق ينتج المترجم خطأ بسبب التحويل الثاني لأن التحويل من فئة أساسية إلى فئة مشتقة غير مسموح .

إلا إذا كانت الفئة متعددة الأشكال (نمط من أنماط oop).

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;

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 <result;
  • return 0;

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

int a;

short s = 1000;

ومن ناحية أخرى، التحويل الضمني لايتطلب أي معامل , ويتم تنفيذها تلقائيا عندما يتم نسخ قيمة من نوع معين إلى نوع آخر موافق .

pd = dynamic_cast(pbb);

  • if (pd==0) cout <<"Null pointer on second type-cast" <<endl;
  • } catch (exception& e) {cout <<"Exception: " <<e.what;}
  • return 0;

b = (B) &d;

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

dynamic_cast وreinterpret_cast وstatic_cast وconst_cast

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

  • dynamic_cast (expression)
  • reinterpret_cast (expression)
  • static_cast (expression)
  • const_cast (expression)
  • أما التحويل الصريح فأن صيغته كالتالي :

pd = dynamic_cast(pba);

if (pd==0) cout <<"Null pointer on first type-cast" <<endl;

}

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

B b = a;

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

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

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

  • class CBase { };
  • class CDerived: public CBase { };
  • CBase b; CBase* pb;
  • CDerived d; CDerived* pd;
  • pb = dynamic_cast(&d); // ok: derived-to-base

a = s;

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

ومن جهة أخرى، مع ذلك هذه التحويلات تعد غير دقيقة أي يمكن أحيانا أن يطلق المترجم رسائل تحذيرية ,ولتجنب ذلك يجب أن نستعمل التحوي الصريح explicit conversion .

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

a = int(s); // functional notation

  • class A
  • {
  • float x,y;
  • };
  • class B
  • {

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

(new_type) expression

new_type (expression)

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

class A {};

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

A a;

int a;

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

}

  • النتائج :
  • Null pointer on second type-cast
  • انظر كذلك
  • لغة السي
  • الكائنات في لغة ++C
  • المتغيرات في لغة ++C
  • أنواع البيانات في لغة ++C

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

كذلك، يوجد نمطين للتحويل الصريح هو الوظيفي (الدالي) functional وc-like :

وعلى صعيد آخر، الكثير من التحويلات , خاصة تلك التي تعبر عن تفسيرات مختلفة في القيمة ,مثل هذه التحويلات تحتاج إلى تحويل صريح .

short s = 1000;

ما رأيك في هذه المقالة؟

📝 هل في هذه المقالة خطأ؟

إذا وجدت معلومة تحتاج تصحيحاً أو إضافة، أو أردت حذف المقالة، أرسل لنا طلباً وسنراجعه.