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

عوامل Stream

جزء من قسم Object Oriented Programming في رحلة C++ على Coddy — الدرس 43 من 104.

تسمح لك معاملات الإدراج (<<) والاستخراج (>>) في التدفق باستخدام فئاتك المخصصة مع std::cout و std::cin. وعلى عكس المعاملات التي قمنا بتغطيتها حتى الآن، يجب تنفيذ هذه كـ دوال غير تابعة للفئة (non-member functions) لأن المعامل الأيسر هو تدفق (stream)، وليس فئتك.

class Point {
    int x, y;
    
public:
    Point(int x, int y) : x(x), y(y) {}
    
    // التصريح كدالة صديقة للوصول إلى الأعضاء الخاصين
    friend std::ostream& operator<<(std::ostream& os, const Point& p);
    friend std::istream& operator>>(std::istream& is, Point& p);
};

std::ostream& operator<<(std::ostream& os, const Point& p) {
    os << "(" << p.x << ", " << p.y << ")";
    return os;
}

std::istream& operator>>(std::istream& is, Point& p) {
    is >> p.x >> p.y;
    return is;
}

يعيد كلا العاملين مرجعاً إلى التدفق، مما يتيح التسلسل مثل std::cout << p1 << p2. يأخذ عامل الإدراج الكائن عبر مرجع const لأنه يقرأ البيانات فقط، بينما يأخذ عامل الاستخراج مرجعاً غير ثابت لأنه يقوم بتعديل الكائن.

الآن يمكنك استخدام Point بشكل طبيعي مع التدفقات (streams):

Point p(3, 4);
std::cout << "Location: " << p << std::endl;    // المخرجات: Location: (3, 4)

Point p2(0, 0);
std::cin >> p2;    // قراءة عددين صحيحين في p2
challenge icon

التحدي

سهل

لنقم ببناء فئة Temperature يمكن استخدامها بسلاسة مع std::cout و std::cin من خلال تحميل عوامل التشغيل (operator overloading) لتدفق البيانات. هذا سيناريو عملي حيث تريد عرض درجات الحرارة بتنسيق مقروء وقراءتها من الإدخال بشكل طبيعي.

ستقوم بإنشاء ملفين لتنظيم الكود الخاص بك:

  • Temperature.h: قم بتعريف فئة Temperature تخزن قيمة بالدرجة المئوية (كـ double) ورمز الوحدة (كـ char، إما 'C' للدرجة المئوية أو 'F' للفهرنهايت). يجب أن تحتوي الفئة الخاصة بك على:

    • أعضاء خاصة (Private members) لقيمة درجة الحرارة والوحدة
    • منشئ افتراضي (default constructor) يقوم بالتهيئة إلى 0.0 درجة مئوية
    • منشئ بمعاملات (parameterized constructor) يأخذ قيمة ووحدة
    • دوال جلب getValue() و getUnit() (كلاهما const)
    • إعلانات صديقة (Friend declarations) لعوامل الإدراج (<<) والاستخراج (>>) للتدفق

    قم بتنفيذ عوامل تشغيل التدفق كدوال غير أعضاء (non-member functions):

    • يجب أن يقوم عامل الإدراج (insertion operator) بإخراج درجة الحرارة بتنسيق VALUE UNIT (على سبيل المثال، 25.5 C أو 77.9 F). استخدم منزلة عشرية واحدة للقيمة.
    • يجب أن يقوم عامل الاستخراج (extraction operator) بقراءة قيمة وحرف الوحدة من التدفق وتخزينهما في كائن Temperature.

    يجب أن يعيد كلا العاملين مرجعاً (reference) إلى التدفق لتمكين التسلسل (chaining).

  • main.cpp: اقرأ درجتي حرارة من الإدخال. يتم توفير كل درجة حرارة في سطر منفصل بتنسيق value unit (على سبيل المثال، 25.5 C).

    قم بإنشاء كائنين من نوع Temperature باستخدام عامل الاستخراج لقراءتهما من std::cin. ثم قم بإخراجهما باستخدام عامل الإدراج بهذا التنسيق:

    Temperature 1: <temp1>
    Temperature 2: <temp2>

    على سبيل المثال، إذا كان الإدخال هو:

    25.5 C
    98.6 F

    يجب أن يكون المخرج:

    Temperature 1: 25.5 C
    Temperature 2: 98.6 F

استخدم std::fixed و std::setprecision(1) من مكتبة <iomanip> لتنسيق قيمة درجة الحرارة بمنزلة عشرية واحدة بالضبط. لا تنسَ حواجز الرأس (header guards) في ملف الرأس الخاص بك.

ورقة مرجعية

تسمح معاملات إدخال التدفق (<<) واستخراج التدفق (>>) للفئات المخصصة بالعمل مع std::cout و std::cin. يجب تنفيذ هذه المعاملات كـ دوال غير تابعة (non-member functions) لأن المعامل الأيسر هو كائن تدفق (stream object)، وليس فئتك.

الصيغة الأساسية

class Point {
    int x, y;
    
public:
    Point(int x, int y) : x(x), y(y) {}
    
    // الإعلان كصديق (friend) للوصول إلى الأعضاء الخاصين
    friend std::ostream& operator<<(std::ostream& os, const Point& p);
    friend std::istream& operator>>(std::istream& is, Point& p);
};

std::ostream& operator<<(std::ostream& os, const Point& p) {
    os << "(" << p.x << ", " << p.y << ")";
    return os;
}

std::istream& operator>>(std::istream& is, Point& p) {
    is >> p.x >> p.y;
    return is;
}

نقاط رئيسية

  • يعيد كلا المعاملين مرجعاً (reference) إلى التدفق لتمكين التسلسل (على سبيل المثال، std::cout << p1 << p2)
  • يأخذ معامل الإدخال (<<) الكائن كمرجع ثابت const لأنه يقرأ البيانات فقط
  • يأخذ معامل الاستخراج (>>) مرجعاً غير ثابت لأنه يقوم بتعديل الكائن
  • استخدم إعلانات friend للسماح لهذه الدوال غير التابعة بالوصول إلى الأعضاء الخاصين

مثال على الاستخدام

Point p(3, 4);
std::cout << "Location: " << p << std::endl;    // المخرجات: Location: (3, 4)

Point p2(0, 0);
std::cin >> p2;    // قراءة عددين صحيحين في p2

جرّب بنفسك

#include <iostream>
#include "Temperature.h"

int main() {
    // TODO: إنشاء كائنين من النوع Temperature
    
    // TODO: استخدم معامل الاستخراج (>>) لقراءة درجتي حرارة من std::cin
    
    // TODO: قم بإخراج درجات الحرارة باستخدام معامل الإدراج (<<)
    // التنسيق:
    // Temperature 1: <temp1>
    // Temperature 2: <temp2>
    
    return 0;
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming