الفئات المكتبية في ++C
الفئات المكتبية
تأتي بيئتي البرمجة بورلاند سي++ وتربو سي++ مزودتين بمكتبة ثرية من الفئات الجاهزة , وأكثر مجموعة منها هي التي سنتناولها باستفاضة في هذا المقال , ألا وهي الحاويات وهي الفئات التي تعطي إمكانية تخزين البيانات أو الكائنات . كما سنعرض لبعض الفئات النفعية , كالأزمنة والعبارات النصية .
لا داعي لإعادة اختراع العجلة
في المقالات السابقة أنشأنا العديد من الفئات النفعية , لتضم كميات كالوقت أو العبارات النصية , كما أنشأنا فئات حاوية للبيانات , بما في ذلك المكادس , والقوائم المترابطة والمصفوفات كل هذه الفئات كانت للدراسة والإيضاح ولكن في التطبيق العملية فإن مكتبة الفئات التي تقدمها بورلاند توفر عناه صياغة مثل هذه الفئات كلما دعت الحاجة لإستخدامها .
صياغة برنامج يتضمن فئة مكتبية
في هذا القيم سوف نبين لك كيف تستفيد من الفئات المكتبية , ويفترض لذلك أنك قد أدخلت مكتبة الفئات خلال عملية التنصيب وأنها حملت لنمطي الذاكرة Medium أو Large لكي يستوعبا هذه الفئات وإلا ظهرت لك رسالة خطأ مثل –text segment exceeds 64K'' " ( ما لم يكن برنامجك بسيطا للغاية ) .
الإصدارات القديمة
تطورت الفئات المكتبية تطورا سريعا فقد ظهرت الفئات الأولي قبل دخول نظام الترميز في السي++ وبالتالي كان الأسلوب هو اشتقاق الفئة المطلوبة من فئة تسمي object , وتطلق بورلاند علي هذه الفئات object containers وقد تكون موجدة ما زالت لعمل توافق مع البرامج القديمة .
وبعد إدخال أسلوب الترميز أخذت الفئات مرونة كبيرة للغاية , لإمكان استخدامها لأي نوع من البيانات , بما في ذلك الأنواع التي يضعها المبرمج , وتطلق بورلاند هذه الفئات Borland International Data Structures (BIDS) وهي معرض حديثنا في هذا المقال , ولذا فيفترض أن نظامك يحتوي عليها كما بفترض أن يحتوي نظامك علي الفئات Tdate, Ttime, string , وهي غير محتواه في أنظمة سابقة .
وأخيرا فإن أنظمة سابقة من بورلاند كانت تسمي فئاتها المكتبية بأسماء تبدأ بالحرف B_ والذي تحول إلي الحرف T . فمثلا ؛ B_ArrayVector قد تحول إلي TArrayVector فإذا كانت لديك التسمية القديمة فبإمكانك أن تحولها للجديدة أو أن تحصل علي نسخة جديدة من مكتبة الفئات لبورلاند وهو المستحسن .
إعداد نظام بورلاند
التعامل مع مكتبة الفئات أمر يسير ما عليك إلا أن تتأكد من اختيار Class Library في الصندوق الحواري New Project عند إنشائك مشرعا جديدا وعليك التأكد من مسار الملف التضميني الذي يحتوي علي الفئة المرادة فمثلا :
#include <classlib\stack.h>// لفات المكادس
#include <classlib\date.h>// لفات المجموعة Tdate
كما توجد أمثلة لاستخدام الفئات المكتبية تحت المسار : .\bc4.5\examples\classlip
وننوه إلي أن مسار الفئة string توجد تحت الدليل include مباشرة وليس classlib علي عكس بقية الفئات .
إعداد نظام التيربو
في نظام التربو توجد كافة الفئات المكتبية تحت الدليل \classlib , والذي يضم تحته عدة أدلة فرعية , منها include, lip , خلاف الأدلة التي بنفس الأسم تحت الدليل الرئيسي , والتي تحتاجها أيضا . وأفضل طريقة لإدخال هذه المسارات بصورة مباشرة هو إدراجها في الصندوق الحواري Directories من قائمة Options . ففي الخانة المعنونة Include Directories أدخل (بفرض أن الدليل الرئيسي هو tc ) :
C:\ tc\classlip\include; c:\tc\include
وفي الخانة المعنونة Library Directories أدخل :
C:\ tc\classlip\lib; c:\tc\lib
وتلاحظ أننا نفصل بين أكثر من مسار بالفاصلة المنقوطة . هذا وتوجد أكثلة عن الفئات المكتبية تحت الدليل classlib\examples .
الفئات النفعية
سنلقي نظرة عاجلة علي ثلاثة مما ضمنته شركة بورلاند من فئات مكتبية في نظاميها ؛ Tdate للتاريخ , Ttime للزمن , و string للعبارات النصية . ويمكنك معرفة المزيد عن إمكانيات الفئات من وثائق الشركة المنتجة .
الفئة TDate
تيسر هذه الفئة حل المشاكل البرمجية التي تتعلق بالزمن , مثل اليوم من أيام الأسبوع الذي كان , أو سيكون , لتاريخ معين , أو عدد الأيام بين تاريخين , وهكذا . فبإستخدامك هذه الفئة يكون تحت إمرتك عدد كبير من الدوال لإجراء حسابات من هذا القبيل , ولعمليات الإدخال والإخراج المرتبطة بالتواريخ .
في هذه الفئة يخزن التاريخ في رقم يسمي Initial number من النوع unsigned long , ولكن تري ما هو التاريخ المنسوب إليه هذا التاريخ ؟ تقول وثائق بورلاند إن يوم 1/1/1901 يوافق اليوم رقم 365.2422 يوما , فإن نقطة البدء تكون العام 4713 ق.م ولكن لأسباب تاريخية ترجع لتعدد نظم التقويم , لا تعتبر التواريخ صحيحة قبل عام 1752 , وهو تاريخ بدء التقويم الجريجوري الساري حاليا .
وعليك أن تلاحظ أنك لو أدخلت تاريخا مثل 1/1/01 , فإن الفئة ستعتبره 1/1/1901 , فإذا كنت تقصد تاريخا يقع في قرن خلاف العشرين , فعليك إدخال السنة بأرقامها الأربعة .
ولإستخدام هذه الفئة يجب تضمين الملف \include\classlib\\date.h , وأيضا include\string.h لأن الفئة TDate تستخدم الفئة string .
ويبين لنا مثالنا التالي عدة استخدامات للدوال المحتواة في هذه الفئة :
Datetest.cpp
// datetest.cpp
// demonstreates the TDate class
// UCS Laboratories
#include <cstring.h>
#include <classlib\date.h>
#include <iostream.h>
void main()
{
char ch;
TDate today;
TDate aday;
cout << "\nToday is " << today << endl;
do
{
cout << "\nEnter date: ";
cin >> aday;
cout << "You entered: " << aday;
aday.SetPrintOption(TDate::Terse);
cout << "\nIn Terse style that's " << aday;
aday.SetPrintOption(TDate::Numbers);
cout << "\nIn Numbers style it's " << aday;
aday.SetPrintOption(TDate::Normal);
cout << "\nDay of year: " << aday.Day();
cout << "\nDay of month: " << aday.DayOfMonth();
cout << "\nName of month: " << aday.NameOfMonth();
cout << "\nName of day: " << aday.NameOfDay();
cout << (aday.Leap() ? "\nLeap year" : "\nNot leap year");
if(aday<today)
cout << "\nThat's " << (today-aday) << " days ago";
else
cout << "\nThat's " << (aday-today) << " days from now";
cout << "\nDay of week: "
<< TDate::DayOfWeek( aday.NameOfDay() );
cout << "\nIndex of month: "
<< TDate::IndexOfMonth( aday.NameOfMonth() );
cout << "\nDo another (y/n)? ";
cin >> ch;
}
while(ch != 'n');
}
يبين البرنامج التاريخ الحالي (مأخوذا من ساعة نظام التشغيل ) , ويسأل المستخدم أن يدخل تاريخا أخر , ثم يظهر بعضا من البيانات المتعلقة به علي النحو التالي :
Today is June 15, 1994
Enter date: 12/31/94
You entered: December, 31, 1994
In Torse style that's 31-Dec, 1994
In Numbers style it's 12/31/1994
Days of the year: 356
Days of the month: December
Name of the day: Saterday
Not leap year
That's 199 days from now
Day of the week 6
Index of the month 12
Do another (y/n)?
ويبين المثال بعضا من إمكانيات الفئة ودوالها المنتمية , ومنها يتضح أن التاريخ يمكن أن يدخل وأن يظهر بعدة صور , بينا ثلاثة منها . ووظائف الدوال المنتمية مفهومة من أسمائها .
الفئة Ttime
تتشابه هذه الفئة مع السابقة بقدر كبير , وتتميز بالمتغير sec من نوع unsigned long يبين عدد الثواني المنقضية من 1/1/1910 إلي تاريخ اليوم . وإليك مثالا يبين بعضا من إمكانيات الفئة :
Temetest.cpp
] تقدم هذه الفئة بعض الخدمات التي لا تهمنا , لكونها بالنسبة لمكان ما لا يظهره المثال , مثل تحديد الوقت بتوقيت جرينتش GMT , وتحديد فترة التوقيت الصيفي Daylight saving [
تخرج هذه الفئة التاريخ مع إظهار الوقت كخيار مبدئي , يمكنك إلغاؤه بجعل معامل الدالة printDate() صفرا علي ما هو موضح بالمثال .
الفئة string
تعنيك هذه الفئة من كثير من التعقيدات الناجمة عن النظر للعبارة النصية كمصفوفة محارف , ويبين لك المثال التالي بعضا من إمكانياتها . سوف ندخل في برنامجنا اسمين , وكلمة واحدة هي ''only'' , ثم نخرج مجموعة من العبارات ] من الناحية اللغوية , لكل عبارة معني مختلف [ علي النحو التالي :
Enter a first name: Sandy
Enter a second name: Chris
She only told Sandy that she loved Chris
She told only Sandy that she loved Chris
She told Sandy only that she loved Chris
She told Sandy that only she loved Chris
She told Sandy that she only loved Chris
She told Sandy that she loved only Chris
She told Sandy that she loved Chris only
وكما تري من المثال , بإمكانك إنشاء كائنات من هذه الفئة بطول صفري أو أن تستهلها بعبارة نصية معينة وتجد في المثال الدوال المنتمية التي تتحكم في العبارات بالحذف والإضافة والوصل .
فئات حاويات البيانات
أكبر مجموعة من الفئات المكتبية هي المتعلقة بحاويات البيانات فهي تقدم أليات لتخزينها بصور متعددة . وتوفر هذه الفئات الكثير من وقت المبرمج ومجهوده . هذه الفئات مبنية علي أساس الترميز ومن ثم لابد من استحداث inistatiate صورة منها بنوع معين من البيانات .
مثال بسيط
سنقدم الأن مثالا يستخدم الفئة TStackAsVector نتوخي فيه البساطة . وسوف ننسخ من الفئة المذكورة فئة بالنوع int , وستري بنفسك كيف أعفتنا هذه الفئة من عناء إنشاء فئة المكدس بأنفسنا :
Stackint.cpp
// stackint.cpp
// tests the TStackAsVector class with type int
#include <classlib\stacks.h>
#include <iostream.h>
void main()
{
TStackAsVector<int> stint; // instantiate a stack for type int
stint.Push(11); // push ints onto stack
stint.Push(12);
stint.Push(13);
while( !stint.IsEmpty() ) // pop ints off stack
cout << stint.Pop() << endl;
}
بالفئة الدالتان المعادتان للمكدس push(), pop() , وفئة ثالثة isEmpty() لتراقب حالة خلوه , وتعيد 1 في هذه الحالة لكي يستخدم في أي عبارة شرطية .
تلخيص فئات الحاويات
قبل أن نسترسل في عرض أمثلة لحاويات , نقدم تلخيصا لها وبيان علاقة بعضها ببعض وتقسم بورلاند فئاتها الخاصة بالحاويات مجموعتين , تسمي الأولي هياكل البيانات الأساسية ''Fundamental Data Structures FDSs والثانية أنواع البيانات المجردة ''Abstract Data Types ADTs وذلك بمفهوم أن المجموعة الثانية تشتق من الأولي , ويظهر في اسمها الفئة التي أشتقت منها مميزا باللفظ As كما في TStackAsVector في حين تنتهي أسماء المجموعة الأولي بالأحرف Imp ونقدم في الجدولين التاليين حصرا بفئات المجموعتين .
جدول هياكل البيانات الأساسية
نوع هيكل البيانات | اسم الفئة | الغرض منها |
تفراع ثنائي Binary trees | TBinarySearch TreeImp | تخزين البيانات في تدرج هرمي |
قائمة مترابطة مزدوجة Double-Linked list | TDoubleList1mp | تخزين متسلسل لعدد غير معروف من البيانات , ويمكن التعامل من أي طرف من القائمة , بطيئة في البحث ولكن سريعة في المحو والإضافة . |
جدول تسكين بيانات Hash Table | THashTable1 mp | تخزين بيانات في جدول لا يبحث فيه بواسطة أرقام دليلية Indexبل بحساب مستخلص من البيانات المخزنة |
متجه Vector | TVectorImp | يماثل المصفوفة , التخزين بناء علي أرقام دليلية , يتميز بسرعة البحث |
جدول أنواع البيانات المجردة
نوع هيكل البيانات | اسم الفئة | الغرض منها |
مصفوفة Array | TArrayAsVector | مصفوفة مشتقة من الفئة Vector |
ترابط Association | TDDAssociation | تجميع مفتاح (مثل كلمة) مع قيمة معينة (مثل تعريف) , عادة في القواميس . |
حقيبة Bag | TBagAsVector | مشتقة من جدولين التسكين , يمكن ظهور البيان أكثر من مرة . |
مكدس مزدوج Deque | TDequeAsVector | مكدس يمكن الدخول والخروج فيه من أحد الناحيتين , مفيد في حالة معرف السعة . |
TDequeList | كالسابق , في حالة عدم معرفة السعة | |
قاموس Dictionary | TdictionaryAsHashTable | مشتق من جدول التسكين يخزن عادة ترابطات (أنظر بعاليه) |
صف Queue | TQueueAsVector(or Tqueue | تخزين بأسلوب الداخل أولا خارج أولا |
TQueueAsDoubleList | كالسابق حينما لا يعرف السعة | |
فئة Set | TSetAsVector (or Set) | مشتق من جدول التسكين , البيانات المتشابهة تخرج مرة واحدة فقط . |
مكدس Stack | TStackAsVector (or Stack) | مكدس , السعة معروفة |
TStackAsList | مكدس , السعة غير معروفة . |
وتلاحظ أن بعض الفئات يمكن أن تشتق بطريقتين , كمتجه AsVector وكقائمة AsList في الأولي تكون السعة معروفة مسبقا وفي الثانية يتسع المخزن ويضيق بحسب الحاجة ولكن علي حساب البطء في التعامل . ويشتق من كل فئة من فئات الجدولين السابقين فئات أخري , فالجدول التالي يبين الفئات المشتقة من الفئة TArrayAsVector . وتلاحظ منه أن الفئات تختلف من حيث :
- ماهية العناصر المخزنة , فمن الفئات ما يخزن مؤشرات للكائنات بدلا من الكائنات ذاتها (تخزين غير مباشر ) , ويتميز بالحرف I (اختصار Indirect ) في التسمية .
- طبيعة التخزين من حيث كونه مرتبا sorted أم غير مرتب , وتميز الأولي بالحرف S في التسمية . وفيها ترتب الأرقام تصاعديا أما أسلوب ترتيب الأنواع المعرفة بواسطة المبرمج فيجب أن يقدمها مستخدما مؤثرات علائقية مزادة التحميل .
- إدارة الذاكرة من حيث كونها قياسية Standard أم يجب أن تقدم من قبل المبرمج Costum باستخدام المؤثرين new, delete . وتميز الأخيرة بالحرف M في التسمية . ويمكن أن تميز الفئات المشتقة من TVectorImp بحرف C للدلالة علي احتوائها علي دالة هي Count() لحصر عدد العناصر المخزنة .
جدول الفئات المشتقة من TArrayAsVector
Memory Management | Sorting | Storing Items | Class Name |
Standard | No | Object | TArrayAsVector |
Standard | No | Pointer | TIArrayAsVector |
Standard | Yes | Object | TSArrayAsVector |
Standard | Yes | Pointer | TISArrayAsVector |
Custom | No | Object | TMArrayAsVector |
Custom | No | Pointer | TMIArrayAsVector |
Custom | Yes | Object | TMSArrayAsVector |
Custom | yes | Pointer | TISArrayAsVector |
.
تعليقات
إرسال تعليق