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

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

التحويل الضمني (بالإنجليزية: 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

```

انظر أيضًا
----------

* لغة السي
* الكائنات في لغة ++C
* المتغيرات في لغة ++C
* أنواع البيانات في لغة ++C

مراجع
-----

1. ↑  *Computer Science With C++ Programming - Class Xi* (بالإنجليزية). Allied Publishers. ISBN:978-81-7023-959-8. Archived from the original on 2020-07-01.

* أيقونة بوابةبوابة تقانة المعلومات
* أيقونة بوابةبوابة برمجة الحاسوب