في هذه المدونة، سندرس كيف تختلف البرمجة الكائنية عن البرمجة الإجرائية، وسنستكشف كيف يتم تطبيق هذا المفهوم في لغة C++.
في بدايات البرمجة، بعد فترة وجيزة من تطوير الحواسيب، كانت البرمجة الإجرائية هي المفهوم السائد. تقوم البرمجة الإجرائية على تنفيذ التعليمات البرمجية التي يُدخلها المستخدم وفق تسلسل مُحدد مسبقًا. ومع مرور الوقت، وازدياد تعقيد التعليمات البرمجية وصعوبة فهمها، ظهر مفهوم البرمجة كائنية التوجه. على عكس البرمجة الإجرائية، تتضمن البرمجة كائنية التوجه إنشاء وحدات صغيرة متعددة تُسمى كائنات، ودمجها لتنفيذ برنامج. وقد وُلدت لغة C++ من خلال دمج مفهوم البرمجة كائنية التوجه هذا في لغة البرمجة الإجرائية C الموجودة آنذاك.
على الرغم من وجود لغات برمجة كائنية التوجه أخرى إلى جانب C++، إلا أن طريقة تطبيقها لمفاهيم البرمجة الكائنية التوجه تختلف. تُطبّق C++ البرمجة الكائنية التوجه من خلال مفهوم "الفئة". في C++، عند استخدام متغير، يجب تحديد نوعه صراحةً. على سبيل المثال، عند استخدام متغير باسم "a"، يجب تحديد ما إذا كان "a" عددًا صحيحًا أو عددًا عشريًا، وهكذا. الفئة ليست نوعًا أساسيًا كالأعداد الصحيحة أو العشرية، بل هي نوع يُعرّفه المبرمج. ضمن فئة مُعرّفة من قِبل المستخدم، يُمكن إنشاء متغيرات ودوال متنوعة. على سبيل المثال، إذا أنشأت فئة باسم "animal"، يُمكنك تعريف متغير عشري باسم "weight" لتمثيل الوزن، كما يُمكنك تعريف دالة لإصدار الأصوات. تُوفّر الفئة البنية فقط، ويُمكن الاستخدام الفعلي من خلال إنشاء متغيرات من نوع الفئة "animal". غالبًا ما يُشبه هذا المفهوم بقالب الخبز والخبز نفسه. تقوم بإنشاء قالب يُسمى فئة، ثم تستخدم هذا القالب لتشكيل المتغيرات كما تُشكّل الخبز. تُسمى المتغيرات التي يتم إنشاؤها باستخدام فئة "كائنات".
تنقسم المكونات الرئيسية لمفاهيم البرمجة الكائنية إلى ثلاثة أقسام رئيسية: الوراثة، والتغليف، وتعدد الأشكال. تُطبّق لغة C++ هذه العناصر داخل الفئات. الوراثة هي مفهومٌ ترث فيه فئةٌ ما وظائفَ من فئةٍ أخرى. على سبيل المثال، لنفترض وجود فئة "حيوان" وفئتين "أسد" و"أرنب". بما أن الأسود والأرانب حيوانات، فإن البرنامج المصمم جيدًا سيجعل فئتي "الأسد" و"الأرنب" ترثان معظم الوظائف من فئة "حيوان". هذا يسمح بكتابة كود مختصر ببساطة عن طريق تحديد أن "الأسد" و"الأرنب" يرثان من فئة "حيوان"، دون الحاجة إلى إعادة كتابة الكود نفسه. هنا، تُسمى فئة "حيوان" التي توفر الوراثة بالفئة الأصلية، بينما تُسمى فئتا "الأسد" و"الأرنب" اللتان ترثان الوظائف بالفئات الفرعية.
يتحكم التغليف في الوصول إلى المعلومات الداخلية للفئة. إذا كانت بيانات مهمة موجودة داخل فئة ما، فإن السماح بالوصول العشوائي إليها يُعدّ أمرًا محفوفًا بالمخاطر. مع ذلك، لا يمكنك جعل الفئة بأكملها خاصة لمجرد حماية بيانات محددة. لذلك، تُستخدم الكلمات المفتاحية لتمييز المعلومات المكشوفة عن المعلومات المخفية.
تعني خاصية تعدد الأشكال أن الاسم نفسه قد يتصرف بشكل مختلف تبعًا للسياق. في لغة C++، عند تعريف دالة، يجب تحديد اسم الدالة ونوع القيمة المُعادة وأنواع وعدد المتغيرات المُمررة إليها بشكل صريح. على سبيل المثال، عند إنشاء دالة لجمع عددين، فإن دالة جمع الأعداد الصحيحة ودالة جمع الأعداد العشرية تؤديان وظائف مختلفة. ومع ذلك، على الرغم من تشابههما، فإن استخدام اسمين مختلفين لكل منهما يجعل تذكرهما واستخدامهما أمرًا بالغ الصعوبة. ولكن في لغة C++، إذا اختلف نوع القيمة المُعادة أو أنواع متغيرات الإدخال أو عدد المتغيرات، تُعتبر الدوال التي تحمل الاسم نفسه دوالًا متميزة. علاوة على ذلك، لا تحتاج الفئة الفرعية إلى تكرار جميع وظائف الفئة الأصلية. على سبيل المثال، إذا كانت هناك دالة تُصدر صوت حيوان، وبما أن كل حيوان يُصدر صوتًا مختلفًا، فيمكن للفئة الفرعية إعادة تعريف هذه الدالة لاستخدام نسختها الخاصة.
لغة C++ هي لغة برمجة تم تطويرها بإضافة بنية نحوية إضافية إلى لغة C، مما يسمح لها باستخدام معظم ميزات C. ولذلك، تُستخدم المؤشرات، وهي إحدى الميزات الرئيسية للغة C، بشكل مباشر في C++. لكل منطقة تخزين في ذاكرة الحاسوب عنوان فريد، ويُستخدم المؤشر للإشارة إلى هذا العنوان. عندما تحتاج دالة ما إلى متغير لتنفيذها، يقوم الحاسوب بنسخ هذا المتغير، وتخزينه في مساحة جديدة، ثم يُنفذ الدالة باستخدام هذا المتغير. بمجرد انتهاء تنفيذ الدالة، يختفي المتغير المنسوخ. على سبيل المثال، عند تنفيذ دالة "swap" التي تُبدل قيم متغيرين، تتغير قيمة المتغير المنسوخ، بينما يبقى المتغير الأصلي دون تغيير. مع ذلك، إذا استقبلت دالة "swap" مؤشرًا إلى المتغير وقامت بتغيير قيمته، فإن المؤشر يُشير إلى العنوان الفريد، وبالتالي تتغير قيمة المتغير فعليًا. كما توفر C++ ميزة المرجع، التي تُمرر المتغير نفسه بدلًا من مؤشر، مما يجعلها مفيدة.
من الميزات الرئيسية الأخرى دعم البرمجة العامة. البرمجة العامة مفهوم مصمم لتعزيز إمكانية إعادة استخدام الكود وتسهيل عمل المبرمج. وتتمثل الميزة الأساسية للغة C++ لتحقيق ذلك في القوالب. كما ذكرنا سابقًا، على الرغم من إمكانية إنشاء دوال متعددة بنفس الاسم، إلا أن إنشاء دوال جمع بسيطة متعددة يُعدّ تبذيرًا للموارد. باستخدام القوالب، يحدد الحاسوب تلقائيًا نوع البيانات (سواء كان عددًا صحيحًا أو عددًا عشريًا) التي تستقبلها الدالة، وينفذ العملية وفقًا لذلك. هذا يقلل من وقت كتابة الكود، ويجعله أكثر إيجازًا، ويحسن من سهولة قراءته.
من عناصر البرمجة العامة مكتبة القوالب القياسية (STL). يُعدّ استخدام البيانات أمرًا بالغ الأهمية في البرمجة. تُنظّم خوارزميات معالجة البيانات رياضيًا، وتُمثّل هياكل البيانات تطبيقاتها. مع ذلك، فإنّ إعادة إنشاء هياكل البيانات من الصفر في كل مرة لا يُضيّع الوقت فحسب، بل لا يضمن أيضًا تحسين الخوارزمية. توفّر لغة C++ هياكل بيانات مُحسّنة من قِبل الخبراء على مستوى اللغة، وهي مكتبة القوالب القياسية (STL). ما على المبرمجين سوى اختيار هيكل البيانات المطلوب واستخدامه.
بهذه الطريقة، توفر لغة C++ العديد من الميزات على مستوى اللغة لتسهيل استخدامها. ولأنها صُممت كامتداد للغة C، فإن اللغة نفسها تتضمن جوانب معقدة. قد يكون تعلم وفهم كل هذه المفاهيم أمرًا صعبًا، ولكن بفضل إمكانيات C++ القوية، لا يزال العديد من المبرمجين يستخدمونها. ويستمر معيار بناء جملة C++ في التطور بمرور الوقت، وسيتم إضافة ميزات متنوعة في المستقبل لتسهيل عمل المبرمجين.