Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

Struct مقابل Class

جزء من قسم البرمجة كائنية التوجه في رحلة C++ على Coddy. الدرس 37 من 104.

في C++، يتطابق struct وclass تقريبًا. يمكن لكليهما امتلاك متغيرات أعضاء، ودوال أعضاء، وبُناة، ودعم inheritance. والاختلاف الوحيد هو مستوى access الافتراضي.

في class، تكون الأعضاء خاصّة افتراضيًا. وفي struct، تكون الأعضاء عامة افتراضيًا:

struct Point {
    int x;    // public بشكل افتراضي
    int y;    // public بشكل افتراضي
};

class Circle {
    double radius;    // private بشكل افتراضي
    
public:
    double getRadius() { return radius; }
};

ينطبق هذا أيضًا على inheritance. يرث struct علنًا بشكل default، بينما يرث class بشكل خاص:

struct DerivedStruct : Base {};    // وراثة عامة
class DerivedClass : Base {};      // وراثة خاصة

بخلاف هذه القيم الافتراضية، لا يوجد فرق تقني. ومع ذلك، فإن الاصطلاح مهم.

يستخدم معظم مبرمجي C++ ‏struct لحاويات البيانات البسيطة ذات الأعضاء العامة (مثل الإحداثي أو التكوين)، ويستخدمون ‏class عندما يكون التغليف والسلوك مهمَّين. إن اتباع هذه الاتفاقية يجعل نية التعليمات البرمجية أكثر وضوحًا للمطورين الآخرين.

challenge icon

التحدي

سهل

لنَبْنِ نظام إعداد بسيطًا يوضّح متى نستخدم struct مقابل class استنادًا إلى اصطلاحات C++. ستُنشئ struct للبيانات البسيطة التي يُفترض أن تكون متاحة بشكل مباشر، وclass للبيانات التي تحتاج إلى التغليف والتحكم في الوصول إليها.

ستُنشئ ملفين لتنظيم الشيفرة:

  • Config.h: عرّف كلًّا من struct وclass يمثّلان نوعين مختلفين من بيانات الإعداد.

    أولًا، أنشئ struct باسم Dimensions: وهو حاوية بيانات بسيطة لـ width وheight (وكلاهما من النوع int). بما أن أعضاء structs تكون عامة افتراضيًا، فينبغي أن تكون قابلة للوصول مباشرةً من دون getters. أضف دالة area() تُرجع حاصل ضرب width وheight.

    بعد ذلك، أنشئ class باسم AppConfig يدير إعدادات التطبيق مع تطبيق التغليف المناسب. يجب أن يخزّن اسم التطبيق (من النوع string) وكائنًا من Dimensions لحجم النافذة. بما أن أعضاء class تكون خاصةً افتراضيًا، فستحتاج إلى جعل واجهتك العامة متاحةً بشكل صريح. وفّر ما يلي:

    • منشئًا يستقبل اسم التطبيق وwidth وheight
    • ‏getter‏ getAppName() يُرجع الاسم
    • ‏getter‏ getWindowSize() يُرجع Dimensions
    • دالة displayConfig() تطبع: "App: <name>, Window: <width>x<height>, Area: <area>"
  • main.cpp: وضّح الفرق بين استخدام struct وclass. اقرأ اسم التطبيق وwidth وheight من الإدخال (ثلاثة أسطر منفصلة)، ثم:
    • أنشئ struct من نوع Dimensions مباشرةً باستخدام قيم width وheight: نفّذ access لأعضائه مباشرةً لطباعة: "Direct struct access: <width> x <height>"
    • أنشئ كائنًا من AppConfig باستخدام القيم الثلاث كلها
    • استدعِ displayConfig() لعرض الإعداد الكامل
    • استخدم getter لاسترداد أبعاد النافذة واطبع: "Via getter - Area: <area>"

يسلّط هذا التحدي الضوء على الاصطلاح التالي: استخدم struct عندما تكون لديك بيانات بسيطة وشفافة (مثل الإحداثيات أو الأبعاد)، واستخدم class عندما تريد التحكم في access وإضافة سلوك حول بياناتك.

حوّل مدخلَي width وheight من سلاسل نصية إلى أعداد صحيحة باستخدام std::stoi(). ولا تنسَ حواجز التضمين في ملف الرأس.

جرّب بنفسك

#include <iostream>
#include <string>
#include "Config.h"

using namespace std;

int main() {
    // قراءة الإدخال
    string appName;
    string widthStr;
    string heightStr;
    
    getline(cin, appName);
    getline(cin, widthStr);
    getline(cin, heightStr);
    
    int width = stoi(widthStr);
    int height = stoi(heightStr);
    
    // TODO: أنشئ هيكل Dimensions مع width و height
    // Access its members directly to print: "Direct struct access: <width> x <height>"
    
    // TODO: أنشئ كائن AppConfig مع appName و width و height
    
    // TODO: استدعِ displayConfig() على كائن AppConfig
    
    // TODO: Use getWindowSize() getter to get dimensions and print: "Via getter - Area: <area>"
    
    return 0;
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم C++ عبر الإنترنت