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

لمحة حول إحدى الميزات الجديدة في لغة C++0x

بدأه Khaled.Alshaya في 25 يناير 2009 · 6 رد · 2,102 مشاهدة · في قسم المواضيع الهامة في قسم السي /سي++
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم و رحمة الله و بركاته,

حديثنا اليوم عن إحدى الإضافات التي تم اعتمادها في لغة ++C, في الحقيقة أن البعض يعتقد أن لغة ++C أصبحت تسمى C++0x و لكن هذا غير صحيح!

C++0x هي محاولة للتعبير عن المقاييس الجديدة للغة, و ليست اسماً جديداً, اللغة التي نمرن أناملنا عليها حالياً هي لغة ++C حسب مقياس C++98!

بشكل عام فإن الميزات التي تم إضافتها تنقسم إلى قسمين,

الثانية : هي إضافات للمكتبة القياسية, و هذه في الحقيقة يمكن التعرف عليها بسهولة.

الأولى :ph34r: : هي إضافات في قلب اللغة! احذر هذا النوع من الإضافات قد يشيب شعرك قبل أن تفهم ما الفائدة, لأن معظم ما على الانترنت هو عبارة عن "تعاريف رسمية" للإضافات و لا يوجد حتى الآن من بدأ بكتابة الدروس حول هذه الإضافات حسب علمي.

عموماً حتى لا يطول الكلام, فإن الكلام اليوم سيدور حول ميزة تسمى Rvalue reference!

أحب أن أطرح مثالاً نبدأ به النقاش ثم نستشف الفائدة,

تخيل معي أنك و خلال كتابة برنامجك العزيز لديك السطر التالي :

string first, second, third;

 

first [color= #000000;]= [color= #A31515;]"Khaled ";

second [color= #000000;]= [color= #A31515;]"Alshaya";

third [color= #000000;]= first [color= #000000;]+ second;
ما يهمنا هو السطر الرابع :

third [color= #000000;]= first [color= #000000;]+ second;

مالذي تعتقد أنه قد حصل في هذا السطر ؟

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

tmp [color= #000000;]= first;

tmp [color= #000000;]+[color= #000000;]= second;

third [color= #000000;]= tmp;

العملية بسيطة, صحيح!

و لكن في السطر الثالث, هناك ما لا أستطيع تسميته خطأ و لكن يمكن أن تسميه خطأ في الفكر البرمجي!

لماذا ؟

سيتم نسخ محتويات الكائن tmp إلى الكائن thrid!

لماذا أصلاً احتجنا لعملية النسخ؟ أليس من الأفضل لو "نقلنا" محتويات الكائن tmp إلى الكائن third!

اصلاً الكائن tmp ليس له فائدة بعد أن قام بجمع النصين, و بالتالي فإن عملية النسخ نفسها خاطئة من ناحية الفكرة!

في هذا السطر مثلاً :

tmp [color= #000000;]= first;
من الخطأ أن نقوم بنقل محتويات الكائن first إلى الكائن tmp!

لأننا قد نستخدم الكائن first بعد ذلك.

هذه هي الإضافة ببساطة شديدة!

الآن لننزل قليلاً و لنتعرف على هذه الميزة بشكل أكثر تفصيلاً,

هنااااااك :lol: في ++C شيء اسمه reference variable :

[color= #0000ff;]int number [color= #000000;]= [color= #ff0000;]0;

[color= #0000ff;]int[color= #000000;]& refNumber [color= #000000;]= number;

في الحقيقة أننا لا يمكننا أن نقوم باسناد قيمة غير ثابتة لهذا المرجع!

كيف تقول قيمة غير ثابتة و انت قد أسندت "المتغير" number ؟

المتغير number يحتوي على قيمة غير ثابتة و لكن عنوانه "ثابت" بالنسبة للبرنامج.

لو عدنا للمثال في بداية الحديث وطبقنا نفس المفهوم :

string[color= #000000;]& refStr [color= #000000;]= functionThatReturnString[color= #000000;]([color= #000000;]); [color= #007f00;]// This is crap.. ERROR

فلا يمكننا اسناد المرجع إلى متغير مؤقت!

هل فهمت القصة ؟

في ++C "الجديدة" سيمكننا كتابة شيء مثل التالي :

string[color= #000000;]&& RrefStr [color= #000000;]= functionThatReturnsString[color= #000000;]([color= #000000;]); [color= #007f00;]// This is good

بالطبع فإن كائن النص في النسخة الجديدة, سيحتوي على ما يسمى بالـ move constructor إضافة طبعاً للـ copy constructor المعتاد,

هناك بالطبع فوائد "كثيرة" غير الذي ذكر و لأنني مصاب بالكسل منذ عدة سنوات فلن أكمل و سأدعكم تبحثون عن الباقي :)

كان هذا لمحة و لا يمكن اعتباره بأي شكل درساً أو مقدمة إنما لمحة بسيطة لا أكثر :)

قبل أن أنهي حديثي هناك ميزة أخرى ضمن الميزات الجديدة تسمى run time concepts :) الفكرة قدمت من مهندسي شركة Adobe و تمت الموافقة عليها. و تعتبر بعداً جديداً في البرمجة لم يسبق أن تطرقت إليه أي لغة من قبل و هو عبارة عن مزيج من الـ run time polymorphism و الـ compile time polymorphism أو ما يسمى بالـ templates ربما نعطي عنها لمحة في المرة القادمة :)

إذا كان لديكم أي سؤال أو استفسار فأن في الخدمة :)

تحياتي ,,

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 25 يناير 2009 في 22:01

#2

الله يزيدك علما إن شاء الله

صراحه مواضيعك اخوي خالد ممتعه ولها طابع خاص

والله يستر علينا من الاضافات لكن كلها تصب في مصلحتنا في الاخير

والله مستغرب الاضافات هذي لانها تزيد من سرعة واداء البرامج

مع العلم اننا وصلنا لسرعات ما نحلم فيها من قبل بسبب الهاردوير

لكن تبقى اضافه ويجب عمل تحديث للغه كل فتره وإلا اعتبرها البعض ممله

ودمتم

تم تعديل هذه المشاركة بواسطة voo في 25 يناير 2009 في 22:29

متغيب

#3

رائع يا رائع :lol:

ألف شكر استاذنا القدير على هذه المعلومات ....

بالنسبة للـ move constructor , الي فهمته عنها كالتالي :

اعطاء عملية مشابهه لهذه العملية

	Time1(Time1 &a){x=a.x;}

ينتج عنها نسخ البيانات من المرجعيه إلى الكائن الحالي .

اما باستخدام الـ move constructor يمكن تحريك البيانات بدون ان تحدث عملية النسخ إلى الكائن الحالي .

Time1(Time1 &&a){x=std::move(a.x)}
llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#4
اقتباس
والله يستر علينا من الاضافات لكن كلها تصب في مصلحتنا في الاخير

والله مستغرب الاضافات هذي لانها تزيد من سرعة واداء البرامج

مع العلم اننا وصلنا لسرعات ما نحلم فيها من قبل بسبب الهاردوير

لكن تبقى اضافه ويجب عمل تحديث للغه كل فتره وإلا اعتبرها البعض ممله

عموماً تحديث لغة ++C ليس هدفه إصدار منتج جديد في الحقيقة :lol: على العكس مصنعي المترجمات اشتكوا من صعوبة تطبيق بعض الإضافات :wacko:

و لهذا تجد المترجمات الغير متوافقة مع آخر المواصفات منتشرة بكثرة,

عموماً ما تعلمته من ++C كله صحيح حسب المواصفات الجديدة, لم يتم إلغاء أي شيء و إنما تم إضافة بعض النواقص التي في الحقيقة كشف عنها منذ زمن ليس بالقليل, فلم يتم تحديث ++C منذ 11 سنة :)

عموماً المواصفات مازالت في طور المسودة النهائية و لم تصدر بعد بشكل رسمي,

تحياتي ,,

#5

أهلاً بك أخي العزيز Time1 :)

في الحقيقة النقطة التي تتكلم عنها هي النقطة المفقودة, و لكن دعني أوضح لك الموضوع حسب استطاعتي.

دعك من كيفية كتابة الـ move constructor ضمن الأصناف و لنركز قليلاً على استدعاء المعامل "=" :

فلو كان لدينا التالي :

string first [color= #000000;]= [color= #A31515;]"Time1";

string second;

second [color= #000000;]= first;

هل سيتم استدعاء الـ move أو الـ copy ؟ هنا السؤال!

في الحقيقة أنه سيتم استدعاء الـ copy constructor.

إذا أردنا استدعاء الـ move فيمكننا فعل ذلك بالطريقة التالي :

second [color= #000000;]= std[color= #000000;]::[color= #808000;]move[color= #000000;](first[color= #000000;]);

طيب لماذا استعملنا الدالة move في حالة الـ move, في الحقيقة ذلك يرجع إلى أن معامل الـ "=" معرف في حالة الـ copy و حالة move!

بالتالي فإن الـ copy هي الافتراضية :)

و لكن إذا أردنا عملية "النقل" يمكننا استخدام الدالة move.

في حالة كانت الطرف الأيمن عبارة عن متغير عائد من دالة على سبيل المثال, فهذا المتغير سيذهب مع الريح بعد المساواة و بالتالي لا معنى لعملية النسخ كما ذكرنا سابقاً و هنا تتم عملية النقل مباشرة دون استخدام الدالة move كما في المثال التالي :

second [color= #000000;]= FunctionThatReturnsString[color= #000000;]([color= #000000;]);

في الحقيقة الدالة move بسيطة إلى أبعد الحدود, و هي فقط لكي نقوم بعمل بإطلاق الـ move داخل الكائن نفسه, انظر إلى تعريفها :

[color= #0000ff;]template [color= #000000;]<[color= #0000ff;]class T[color= #000000;]>

[color= #0000ff;]typename remove_reference[color= #000000;]<T[color= #000000;]>[color= #000000;]::[color= #808000;]type[color= #000000;]&&

move[color= #000000;](T[color= #000000;]&& a[color= #000000;])

[color= #000000;]{

    [color= #0000ff;]return a;

[color= #000000;]}

بكل بساطة تعيد الكائن على أنه rvalue و بالتالي ينطلق الـ move constructor بدلاً من الـ copy في الحالة الافتراضية.

أتمنى أن تكون الفكرة قد وصلت, الملخص لما قيل :

إذا كان الطرف الأيمن من المساواة عبارة عن متغير لدينا اسمه, فإن الـ copy هي الافتراضية مادمنا لم نستخدم move function و إذا كان الطرف الأيمن لا اسم له أي كان متغيراً مؤقتاً فإن الـ move يطبق افتراضياً...

الآن لدينا السؤال التالي :

ماذا لو كتبنا السطر التالي :

[color= #0000ff;]int number [color= #000000;]= FunctionThatReturnsInt[color= #000000;]([color= #000000;]); [color= #007f00;]// the function returns int :)

مالذي سيحصل بالضبط ؟ :P

تحياتي ,,

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 25 يناير 2009 في 23:04

#6

ممتاز يا خالد :) .

وصراحه اللغه كل شويه تأخذ منحنى جديد يسهل على مستخدم الكلاسات الأستخدام ، ويُصعب على الClass Writer كثيرا :) .

يعني النظريه منها هو استخدام move بدلا من النسخ العادي ، وذلك عن طريق عمل Overload للcopy constructor و assignment operator ، وبمجرد عمل كائن جديد بlvalue سوف يتم استدعاء النسخ العاديه (التي لا تدعم move) ، واذا تم استدعائه بrvalue سوف يتم استدعاء النسخ التي تستخدم الmove semantic .

دمت بخير ،،

http://informatic-ar.com منصة تعليمية عربية في علوم الحاسب والبرمجة

https://moalfat.com  للكتب الالكترونية والكورسات التعليمية

Everything we see now is just an engineering solution based on old science

#7

جميل جدا اخي خالد

ولكن هل تم تطبيق هذه الإضافة في الـ Visual C++ 2010 ??

تم تعديل هذه المشاركة بواسطة mandareka في 7 مارس 2009 في 15:58

دولة الخلافة الاسلامية في المخاض الاخير وميلادها قريب

حزب التحرير : التزم الطريق الصحيح الشرعي الوحيد لاعادة دولة الخلافة الاسلامية .

الامة الاسلامية متعطشة لقيادة مخلصة لتذوق حلاوة النصر ولن يكون ذلك الا بعودة الخلافة الاسلامية

الامة الاسلامية تحتاج لاحداث تسحقها سحقا وتمعسها معسا لتفكر تفكيرا جماعيا بالتغير لان وحدة المشاعر لوحدها لاتكفي وهذة الاحداث كلها خير

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