|
تمهيد:
الموضوع بخصوص const في لغة ++C. هذه الكلمة const خمسة حروف فقط و هي اختصار لكلمة constant و التي تعني في اللغة الإنجليزية بالثابت أي ضد المتغير variable.
++++++++++ الدرس الاول++++++++++
رياضياً و تحديداً (في علم الجبر) فإن الثابت معلوم و كما يدل اسمه عليه (ثابت) لا يتغير اثناء العملية الحسابية بعكس المتغير الذي يكون غير معلوم و غير متنبأ به.
استعمال الثوابت و المتغيرات في لغات البرمجة و تحديداً لغتنا هنا ++C تتعامل مع الثوابت و المتغيرات بنفس هذا المفهوم الرياضي الجبري, و لكن مع انحراف بسيط تقنياً و آلياً. في لغة ++C الثوابت إما بتكون متناثرة Literals أو ثوابت معمولين بواسطة الكلمة const و هي موضوعنا في هذا الدرس.
طبعاً أنا لستُ مهتمة بخصوص الثوابت المتناثرة في هذا الدرس و التي تكون على حالها الطبيعي الخام متل:
"My name is Raghad" 'a' true 20.33 22
|
ربما البعض و تحديداً المبتدئين منّا في لغة ++C يظنوا أن كلمة const فقط تُستعمل لإنشاء ثابت رياضي جبري فقط متل:
//Algebraic constant... const float PI = 3.14159;
|
هذا استعمال واحد فقط لكلمة const.
السطور الموجودة في الشيفرة التالية تحتوي على اشهر استعمالات الكلمة const إذا كنتم على اطلاع و معرفة تامة بكل ما فيها بإمكانكم تجاهل الدرس(طبعا ما رايحة ازعل) :cry: .
//An algebraic constant const float PI = 3.14159; //The following is the famous one (The copy constructor) MyClass (const MyClass& obj); //The following is Object-Oriented use only which is used frequently //for getter member function(s) (read-only) int getter()const; //A constant pointer int* const p = &i; // must be initialized. //A pointer to a constant const int *p; //A constant pointer to a constant const int* const p = &I; //It must be initialized as well...
|
حقيقة const في لغة ++C:
- الحقيقة الأولى:
في الحقيقة هذه الكلمة const ليست إلا "قُفل". يعني دائما لما بتتعاملوا مع كلمة const تذكروا الصورة التالية:

ليست إلا قُفل لحماية شيء ما من التغيير. (مش اكتر)...
لنتأكد!
بنعمل نسخ لصندوق الشيفرة السابقة (المحتويات) و بنحذف كلمة const و شاهدوا الفرق.
//It's a variable float PI = 3.14159; //A regular constructor MyClass (MyClass& obj); //A normal function/method... int getter(); //A pointer int* p = &i; //Optional initial value //A pointer which is similar to the previous pointer without initial value int *p; //Again it is a normal pointer that has an optional initial value... int* p = &I;
|
اعملوا مقارنة مرة تانية بين الشيفرة هذه و الشيفرة السابقة! بتلاحظوا أن const مهمة طبعاً و غيرت اشياء بالشيفرة و لكن ليست إلا قُفل يمنعنا من تغيير قيمة شيء معين.
متل المتغير الأول PI الآن نستطيع تغيير قيمته اثناء البرنامج بكل بساطة لأن const كانت مانعتنا من إعادة تعين قيمة للمتغير PI. و ايضاً كل الشيفرة الآن ممكن تغير كل القيم لكل الأشيا التي كانت const متضمنة في تعريفاتهن البرمجية.
- الحقيقة التانية:
أي شيء متعلق بالكلمة const يجب أن يأخذ قيمة استهلالية Initial value قبل تنفيذ البرنامج. و تتم هذه الطريقة بواسطتنا يدوياً او بطريقة ما بواسطة البرنامج اثناء عملية الجمع للبرنامج At the compile-time. و بتلاحظوا بأني كاتبة تعليقات في صندوق الشيفرة (بدون const) بأن القيمة الإستهلالية ليست ضرورية في كل الحالات.
++++++++++ الدرس الثاني++++++++++
بنكمل درسنا السابق حول الكلمة const. و كما ورد في الدرس السابق مشيرةً إلى أن هذه الكلمة const مجرد قُفل تمنعنا(المبرمجون أو المستخدمون) او تمنع نفس البرنامج من تعديل شيء معين أو تغير قيمته.
ما هو هذا (الشيء المعين المقصود هنا؟)...
حسناً, بشكل عمومي التغيرات تطرأ على إحدى الأشيا الموجودة بالقائمة التالية:
c -- متغيّر ما... a variable.
o -- مؤشر ما... a pointer.
n -- مرجع ما... a reference.
s -- اقتراح ما... an argument.
t -- قيمة مسترجعة... a return value
بتلاحظوا, ترقيم القائمة بعدد حروف كلمة const.
,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.
بكل بساطة السطر التالي عبارة عن متغيّر لا يمكن تغيير قيمته و يجب أن نعطيه قيمة استهلالية فوراً وقت تعريفه و إنشائه(بنفس السطر):
بتلاحظوا (الدزن أو الدرزن بلهجتنا العامية) دائماً و بشكل عمومي عبارة عن تناعشر شيء, و لن نحتاج لتغيير هذه القيمة طيلة فترة حياة البرنامج و لا نريد أي شخص يعمل تغيير لهذه القيمة لاحقاً. بكلمة const عملنا قفل لهذه القيمة.
,.,..,.,.,.,.,.,.,.,.,.,.,.,
المؤشرات المضاف إليها كلمة const:
- قُفل لحماية المؤشر من أن يشير إلى متغير أو كائن آخر. Constant Pointer
المؤشر بشكل طبيعي يحمل قيمة معينة, هذه القيمة دائماً هي عبارة عن عنوان بالذاكرة لمتغيير(لكائن) آخر. و بشكل طبيعي ايضاً بل بشكل معروف دائماً بأن المؤشر مرن و ممكن أن يشير إلى عنوان آخر و يتنقل ليشير إلى عنوان آخر و هكذا...
و لكن بعض الأحيان لا نريد هذا المتغير أن يشير إلى عنوان بالذاكرة إلا فقط ذلك العنوان الذي يحتويه اثناء إنشائه. بكل بساطة المثال التالي يشرح هذه الفكرة بديهياً.
int a, b; int* const ptra = &a; //must be initialized... a = 20; b = 16; : : ptra = &b; //error, ptra can only point to (a) which it was initialized to point.
|
هذا النوع من المؤشرات فقط يشير إلى العنوان الموجود بقيمته الإستهلالية, في الشيفرة السابقة هي عنوان المتغير a. و لاحظوا أننا لا نستطيع اثناء البرنامج أن نجعل هذا المؤشر يشير إلى عنوان آخر. و لكن نستطيع أن نتعامل مع المتغير a بشكل طبيعي كمتغير نستطيع تغير قيمته اثناء البرنامج و نستطيع تعديل قيمة المتغير a بواسطة المؤشر الخاص به بشكل طبيعي ايضاً. (حاولوا تطبيق الشيفرة لتكتشفوا الفكرة).
ملاحظة مهمة (سر خطير):
النوع السابق من المؤشرات الثابتة Constant Pointer تماماً متل المرجع reference العادي.
هذا يعني أن الشيفرة السابقة متساوية تماماً للشيفرة التالية:
int a; int &refa = a; //must be initialized... int b = 20; refa = b; // Ok, but don't let it fool you. this is not an address-oriented assignment
|
السطر refa = b الأخير, ليس إلا فقط تعين قيمة b إلى المتغير a و ليست تعين عنوان b إلى المرجع refa...
و طبعاً نصائح الخبراء دائما بتقول بأن نستعمل المراجع references عوضاً عن المؤشرات pointers بقدر الإمكان و ما دام ذلك ممكناً.
- مؤشر يُشير إلى ثابت a pointer to a constant:
هذا النوع من المؤشرات يستطيع الإشارة إلى أي عنوان بالذاكرة اسناء دورة و حياة البرنامج و لكن كلمة const مُضافة إلى هذا النوع من المؤشر تمنعنا من تغيير قيمة ذلك الكائن او ذلك المتغير بواسطة هذا المؤشر و يمكن الإشارة بهذا المؤشر إلى متغيرات عادية او ثوابت و لكن لن نستطيع تغيير قيمهن بواسطته.
- مؤشر ثابت إلى ثابت... a constant pointer to a constant:
هذا النوع ببساطة متل النوع التاني a pointer to a constant و لكن لا يستطيع أن يشير إلى كائن او متغير (عنوان) آخر غير ذلك العنوان بالقيمة الإستهلالية عند إنشائه.
int a, b; a = b = 540 // a constant pointer to a constant const int* const p = &a// must be initialized... *p = 10;// error, cannot change the value of the (a) p = &b; // error, cannot point to another variable... : :
|
هذا النوع من المؤشرات Read-only لقراءة قيمة كائن واحد فقط و تتبع هذا الكائن فقط طيلة فترة حياة البرنامج...
,.,..,..,.,.,.,.,,..,,.,.
إن شاء الله بنكمل الباقي بمشاركة مستقلة...
++++++++++ الدرس الثالث++++++++++
الآن نتناول حالة خاصة تُستعمل فقط مع البرمجة الكائنية { P :shock: :shock: }:
دائماً بنستعملها لإنشاء أصناف عالية الجودة هندسياً و كذلك بيستعملوها مطوري Qt داخل الأصناف لجلب (قراءة) قيمة حالة معينة للكائنات Object' State.
متل:
bool acceptDrops () const QString accessibleDescription () const QRect contentsRect () const Qt::ContextMenuPolicy contextMenuPolicy () const void ensurePolished () const Qt::FocusPolicy focusPolicy () const const QFont & font () const QPalette::ColorRole foregroundRole () const QRect frameGeometry () const const QRect & geometry () const QWidget * childAt ( int x , int y ) const
|
لاحظوا هذه الدوال فقط من QWidget و هناك المزيد... و كل هذه الدوال بتنتهي بالكلمة const. بكل بساطة الكلمة const هنا عبارة عن (قُفل) تمنع من إعادة تعيين قيمة لأي data member (متغير او كائن) معرّف داخل هذا الصنف. فقط يمكننا قراءته (استرجاع قيمته) او التعامل معه بأي طريقة اخرى و لكن بدون أن نعين قيمة له بواسطة أداة التعيين "=".
,.,..,.,.,.,.,.,.,.,,..,.,.,
الشيفرة التالية بتشرح كل ما سبق:
class MyClass{ public: int getX() const { int y, z; y = z = 10; // allowed, because z,y aren't data member... _x = z + y; //Error, because (_x) is a data member... return _x; //typical use for such member functions (getter).. } private: // _x is a data member... int _x ; };
|
هذا كل شيء حول فكرة استعمال const في بناء هياكل القراءة فقط read-only structure. تماماً متل الدالة getX الموجودة بداخل MyClass و الدوال الموجودة بالصنف QWidget الموجودة بصندوق الشيفرة الأولى.
,..,.,.,.,.,.,.,,..,,.,.
إن شاء الله سنكمل باقي الدرس لاحقاً.
bye...
| إسم الكاتب |
تاريخ الإضافة |
التقييم / المقيمين |
زيارات الدرس |
| رغـد |
24/03/2009 |
2 / 2 |
1639 |
|