الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

Type Conversion

بدأه C++er في 23 يونيو 2011 · 7 رد · 728 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

أنظر معي الكود التالي:

struct Number
{
   Number(){}
   Number(int value) {}
};

void merge(const Number** array, int length) {}


int main()
{
   Number* n[] = { &Number(2), &Number(3), &Number(5), &Number(7) };

   merge(n, 4); // C2664
   //merge((const Number**)n, 4); // uncomment to resolve
}

عند التنفيذ تفشل عملية الترجمه و السبب هو عدم قدرة المترجم على تحويل Number* [4] إلى const Number** و عند إضافة const لتعريف المتغير n يتم إكمال عملية الترجمه دون مشاكل أو بإضافة عملية التحويل بشكل يدوي فما السبب؟؟ أليس وجود const بتعريف المعامل array هو وعد بعدم تغيير قيمة ما يتم تمريره؟

و الله ولي التوفيق

تم تعديل هذه المشاركة بواسطة محمد علاء الدين في 23 يونيو 2011 في 23:12

مدونتي: C++ Tips and Tricks

#2

اذا كانت ال function تأخذ reference parameter ، وكان النوع مختلف (هي تعتبره const وانت لم ترسل const) ، فأنها ستخلق temporary objects لتحتوي هذه البيانات وفي ال compilers الحديثه لا يمكن انشاء ال reference بي قيم مؤقته فبتالي تعيد هذا الخطاء.

راجع

http://msdn.microsoft.com/en-us/library/s5b150wd(v=vs.71).aspx

#3

السلام عليكم ...

بصراحة السؤال صعب و حيرني, و لكن هذا ما عندي.

أولاً بالنسبة للسطر التالي:

Number* n[] = { &Number(2), &Number(3), &Number(5), &Number(7) };

n عبارة عن مصفوفة مؤشرات, قمت بتهيئتها بعنواين متغيرات مؤقتة, هل هذا يصح أصلاً؟

ثانياً, أذكر أننا تكلمنا في موضوع الـ Aliasing هذا مرة سابقة:

ال Overloading و ال Type Checking

#4
اقتباس
n عبارة عن مصفوفة مؤشرات, قمت بتهيئتها بعنواين متغيرات مؤقتة, هل هذا يصح أصلاً؟

مدى حياة هذه المتغيرات داخل scope الداله main، مثلها مثل ان تمرر temporary object كمعامل:

void test(const Number& n) {}

int main()
{
  test(Number(10));
}

حياة الكائن الذى سيتم إنشائه ليتم تمريره كمعامل ستنتهي بمجرد الرجوع من الداله test.

بالنسبه لنقطة المتغيرات المؤقته، حتىلو افترضنا انها متغيرات فعليه فإعتراض المترجم سيظل كما هو:

int main()
{
   Number n1(2);
   Number n2(3);
   Number n3(5);
   Number n4(7);

   Number* n[] = { &n1, &n2, &n3, &n4 };

   merge(n, 4); // C2664
}

المشكله لازالت قائمه و لا اعرف لماذا تحدث، قمت بالبحث داخل وثائق اللغه و لكنها معقده نوعا ما و لا استطيع الوصول لإجابه محدده!!

اقتباس
ثانياً, أذكر أننا تكلمنا في موضوع الـ Aliasing هذا مرة سابقة:

راجعته كذا مره قبل ما أضع الموضوع ده، انا كنت فاكر ان موضوع الـ cv modifier ينطبق على array of characters.

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

مدونتي: C++ Tips and Tricks

#5

عزيزي محمد,

بالنسبة للمتغيرات المؤقتة في مثالك, فإن حياتها تنتهي بمجرد الخروج من الـ Initialization, راجع 12.2

و على فرض أننا لم نستخدم متغيرات مؤقتة كما في مثالك, فإن الموضوع الذي أشرت إليه سابقاً ينطبق على سؤالك. لا أدري لماذا فهمت أن الموضوع ينطبق على char فقط, بينما كان مثالاً على المشكلة في الوثائق و لكنه ينطبق على المؤشرات حيث درجة الـ indirection عبارة عن 2 أو أكثر.

تحياتي...

1
#6
اقتباس
بالنسبة للمتغيرات المؤقتة في مثالك, فإن حياتها تنتهي بمجرد الخروج من الـ Initialization, راجع 12.2

كلامك صحيح، عندما جربتها على مترجم إنتل إعترض و السبب أن المعامل address-of يتطلب lvalue.

الإمتدادات بمترجم مايكروسوفت كانت هى السبب.

اقتباس
و على فرض أننا لم نستخدم متغيرات مؤقتة كما في مثالك, فإن الموضوع الذي أشرت إليه سابقاً ينطبق على سؤالك. لا أدري لماذا فهمت أن الموضوع ينطبق على char فقط, بينما كان مثالاً على المشكلة في الوثائق و لكنه ينطبق على المؤشرات حيث درجة الـ indirection عبارة عن 2 أو أكثر.

إختلط على الأمر فيها.

شكرا لك اخى خالد.

و الله ولي التوفيق

مدونتي: C++ Tips and Tricks

#7

السلام عليكم

هناك فرق بين المؤشرات الثابثة و المؤشرات على الثوابث.

الكود التالي سيعمل لكن المتغير n سيحتوي على عناوين متغيرات مؤقتة:

#include <iostream>

using namespace std;

struct Number
{
   Number(){}
   Number(int value) {}
};

void merge( Number** const array, int length) {}


int main()
{
   Number* n[] = { &Number(2), &Number(3), &Number(5), &Number(7) };

   merge(n, 4); // C2664
   //merge((const Number**)n, 4); // uncomment to resolve
}

تم تعديل هذه المشاركة بواسطة xpero في 25 يونيو 2011 في 00:40

#8

أهلاً أخ محمد, الأسئلة التي تضعها تجعل أي شخص يعيد التفكير في ما يقوله مرتين قبل أن يصل إلى نتيجة :P

أفضل شيء هو الترجمة بأعلى مستوى تحذير مع إبطال أي extensions يقدمها VC:

/Wall و Za/

1

مواضيع مشابهة