• 0
محمد علاء الدين

Type Conversion

سؤال

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


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 هو وعد بعدم تغيير قيمة ما يتم تمريره؟

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

تم تعديل بواسطه محمد علاء الدين
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

7 إجابة على هذا السؤال .

  • 0

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

راجع

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

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

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

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

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

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

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

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

ال Overloading و ال Type Checking

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0
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 بتعريفه الموجود فى هذه المشاركه او المشاركه الأولي، حقيقة انا لا استطيع فهمها.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

عزيزي محمد,

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

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

تحياتي...

1

شارك هذا الرد


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

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

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

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

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

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

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

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

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

الكود التالي سيعمل لكن المتغير 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
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

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

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

/Wall و Za/

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .