Programming Basics SQL HTML CSS JavaScript React Python C++ Java JavaFX Swing Problem Solving English English Conversations Computer Fundamentals Linux Learn Typing

تحديات برمجيةالتحدي الثاني - الحل بلغة C++

فكرة المشروع

في هذا التمرين سنفترض أننا نقوم بتخزين بيانات لمؤسسة صغيرة.
البيانات التي نريد تخزينها هي التالية:

  • الموظفين الذين يعملون في المؤسسة (الإسم, الهاتف, الجنس, دوام العمل, أيام العمل).
  • الزبائن الذين يشترون من المؤسسة (الإسم, الهاتف, الجنس, البريد الإلكتروني).
  • المنتجات التي تبيعها المؤسسة (إسم المنتج و سعره).
  • الفواتير الخاصة ببيع المنتجات (تاريخ البيع, هل تم الدفع أم لا, بيانات المشتري, المنتجات التي تم شراءها).

ملاحظة: رقم التعرفة لكل من الأشخاص, المنتجات, الفواتير يجب أن يتم إعطاؤه لهم بشكل تلقائي.


الشكل العام لأقسام المشروع


شرح أقسام المشروع

Person يمثل المعلومات المشتركة بين الموظف و الزبون.
Client يمثل المعلومات الإضافية الخاصة بالزبون و غير موجودة عند الموظف.
Employee يمثل المعلومات الإضافية الخاصة الموظف و غير موجودة عند الزبون.
Product يمثل أي منتج تبيعه الشركة.
Order يمثل فواتير بيع المنتجات و لاحظ أن كل فاتورة سيتم فيها بيع مجموعة من المنتجات و كل فاتورة سيتم إصدارها لشخص محدد.
add_product(): مهمتها إضافة منتج جديد.
add_person(): مهمتها إضافة شخص جديد سواء موظف أو زبون.
add_order(): مهمتها إضافة فاتورة جديدة.
remove_product(): مهمتها حذف منتج من خلال id المنتج الذي نمرره لها عند استدعائها.
remove_person(): مهمتها حذف شخص من خلال id الشخص الذي نمرره لها عند استدعائها.
remove_order(): مهمتها حذف فاتورة من خلال id الفاتورة الذي نمرره لها عند استدعائها.
print_person_info(): مهمتها عرض كل معلومات الشخص من خلال id الشخص الذي نمرره لها عند استدعائها.
print_product_details(): مهمتها عرض كل معلومات المنتج من خلال id المنتج الذي نمرره لها عند استدعائها.
print_order_details(): مهمتها عرض كل معلومات الفاتورة من خلال id الفاتورة الذي نمرره لها عند استدعائها.
print_person_orders(): مهمتها عرض كل فواتير الشخص من خلال id الشخص الذي نمرره لها عند استدعائها.
print_extra_info(): مهمتها عرض كل المعلومات المتوفرة حول الشخص سواء كان موظف أو زبون.

قم بتحويل الرسم إلى كود. ثم قم بإنشاء مجموعة موظفين, زبائن, منتجات و فواتير. و قم بتجربة جميع الدوال في البرنامج.


إرشادات

المشروع يجب أن يحتوي على 6 كلاسات أساسية هي Person, Client, Employee, Product, Order و Company.

كل كلاس منهم سيكون هناك ملفين في المشروع من أجله:
- ملف إمتداده .h يمثل الشكل العام لما يحتويه الكلاس.
- و ملف إمتداده .cpp يمثل طريقة عمل كل شيئ تم وضعه في الملف .h و هذا من قواعد لغة C++.

ملاحظة: سنقوم بوضع كود الملفين التابعين لنفس الكلاس ( ملف الـ .h و ملف الـ .cpp ) تحت بعضهما حتى نسهّل عليك قراءة الشرح.


معلومة

لإعطاء رقم id موحد لكل كائن يتم إنشاؤه, يمكنك تعريف متغير ثابت ( static ) في الكلاس و جعله أيضاً private حتى لا يمكن تعديل قيمته بشكل يدوي من خارج هذا الكلاس. بعدها تقوم فقط بجعل قيمته تزيد 1 كلما قمت بإنشاء كائن من هذا الكلاس و من ثم تضع قيمته في المتغير id.

ملاحظة: سنقوم بإنشاء متغير نوعه private static إسمه idIncrementer في الكلاسات Person, Product و Order من أجل هذا الهدف فقط.

الكائنات التي سننشئها من الكلاسات Client و Employee و التي ترث من الكلاس Person ستلاحظ أننا سنتعامل معها من خلال المؤشرات ( Pointers ) لأننا سنحتاج ذلك من أجل تطبيق مبدأ تعدد الأشكال ( Polymorphism ). مبدأ تعدد الأشكال سنطبقه في هذا المشروع عندما نجهز الكود للتعامل بشكل أساسي مع الكلاس Person و مع أي كلاس يرث منه. و هنا سنفعل ذلك من أجل الكلاس Client و الكلاس Employee.


الحل بلغة ++C

Person.h
#ifndef PERSON_H
#define PERSON_H

#include <string>
#include <iostream>
using namespace std;

// الذي يمثل المعلومات الأساسية التي سيملكها أي شخص Person هنا قمنا بذكر الخصائص, الدوال و الكونستركتور الذي يحتويه الكلاس
class Person
{
    public:
        // هنا قمنا بتعريف الخصائص الأساسية التي يجب أن يملكها أي شخص
        int id;
        string name;
        string phone;
        string gender;
        
        // هنا قمنا بتحديد شكل كونستركتور الكلاس و الذي سنستخدمه لإسناد قيم للكائن الذي ننشئه من هذا الكلاس بشكل مباشر
        Person(string name, string phone, string gender);
        
        // السبب في ذلك أننا سنجعل Person هنا قمنا بتعريف هذا الدالة لأننا نريد أن تكون موجودة في أي كلاس يرث من الكلاس
        // Person حتى يطبع المعلومات الأخرى التي يملكها بالإضافة إلى التي ورثها من الكلاس Override أي كلاس يرثها يفعل لها
        virtual void printExtraInfo();

    private:
        // لأننا بنفس الوقت نريده أن يكون موحداً لجميع private و static قمنا بتعريفه كـ idIncrementer الثابت
        // الكائنات التي ننشئها من هذا الكلاس و الكلاسات التي ترث منه و لا يمكن التعامل معه بشكل مباشر من أي كلاس آخر
        static int idIncrementer;
};

#endif

Person.cpp
#include "Person.h"

// idIncrementer هنا قمنا بتحديد القيمة الأولية للثابت
int Person::idIncrementer = 0;

// Person هنا قمنا بتحديد كيف سيتم إسناد القيم الأولية عند إنشاء كائن من الكلاس
// id تزيد 1 في كل مرة و من ثم يتم وضعها في الخاصية idIncrementer لاحظ أننا جعلنا قيمة
// الخاصة بالكائن. القيم الأخرى التي سيتم تمريرها للكائن سيتم تخزينها بشكل مباشر في خصائص الكائن
Person::Person(string name, string phone, string gender)
{
    idIncrementer++;
    this->id = idIncrementer;
    this->name = name;
    this->phone = phone;
    this->gender = gender;
}

// لأننا لا ننوي استدعاءها بشكل مباشر من هذا الكلاس printExtraInfo() لاحظ أننا أبقينا الدالة
// الكلاسات التي ترث من هذا الكلاس Override التي ستفعل لها printExtraInfo() بل ننوي استدعاء الدالة
void Person::printExtraInfo() { }

Client.h
#ifndef CLIENT_H
#define CLIENT_H

#include "Person.h"  // حتى نستطيع الوراثة منه Person.h قمنا بتضمين الملف

// الذي يمثل المعلومات الأساسية التي سيملكها أي زبون Client هنا قمنا بذكر الخصائص, الدوال و الكونستركتور الذي يحتويه الكلاس
// email لأن الزبون عبارة عن شخص عادي و لكنه يملك خصاصية إضافية هي الخاصية Person لاحظ أننا جعلناه يرث من الكلاس
class Client: public Person
{
    public:
        // هنا قمنا بتعريف الخاصية الإضافية التي سيملكها الموظف
        // id, name, phone, gender, salary, workingTime :أصبح يملك الخصائص التالية Client إذاً الكلاس
        string email;
        
        // email مضافاً إليه الخاصية Person لاحظ أن شكل كونستركتور الكلاس هو نفسه شكل كونستركتور الكلاس
        Client(string name, string phone, string gender, string email);

        // Person التي ورثها هذا الكلاس من الكلاس printExtraInfo() للدالة Override لأننا ننوي أن نفعل printExtraInfo() هنا قمنا بتعريف الدالة
        void printExtraInfo();
};

#endif

Client.cpp
#include "Client.h"

// Client هنا قمنا بتحديد كيف سيتم إسناد القيم الأولية عند إنشاء كائن من الكلاس
// Client و هو سيتولى أمر تخزينها في الخصائص التي ورثها الكلاس Person سيتم تمريرها لكونستكتور الكلاس gender و phone ,name القيم التي يتم تمريرها للباراميترات
// Client سيتم إسنادها بشكل مباشر للخاصية التي تم تعريفها بداخل الكلاس email القيمة التي يتم تمريرها مكان الباراميتر
Client::Client(string name, string phone, string gender, string email)
: Person(name, phone, gender)
{
    this->email = email;
}

// Person التي تم وراثتها من الكلاس printExtraInfo() للدالة Override هنا كأننا فعلنا
// Client عند استدعاء الدالة من كائن أصله من الكلاس email قمنا بتعريف هذه الدالة بهدف طباعة قيمة الخاصية
void Client::printExtraInfo()
{
    cout << "Email: " << this->email << "\n";
}

Employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H

#include "Person.h"  // حتى نستطيع الوراثة منه Person.h قمنا بتضمين الملف

// الذي يمثل المعلومات الأساسية التي سيملكها أي موظف Employee هنا قمنا بذكر الخصائص, الدوال و الكونستركتور الذي يحتويه الكلاس
// workingTime و salary لأن الموظف عبارة عن شخص عادي و لكنه يملك خصائص إضافية هي Person لاحظ أننا جعلناه يرث من الكلاس
class Employee: public Person
{
    public:
        // هنا قمنا بتعريف الخصائص الإضافية التي سيملكها الموظف
        // id, name, phone, gender, salary, workingTime :أصبح يملك الخصائص التالية Employee إذاً الكلاس
        float salary;
        string workingTime;
        
        // salary و workingTime مضافاً إليه الخاصيتين Person لاحظ أن شكل كونستركتور الكلاس هو نفسه شكل كونستركتور الكلاس
        Employee(string name, string phone, string gender, float salary, string workingTime);

        // Person التي ورثها هذا الكلاس من الكلاس printExtraInfo() للدالة Override لأننا ننوي أن نفعل printExtraInfo() هنا قمنا بتعريف الدالة
        void printExtraInfo();
};

#endif

Employee.cpp
#include "Employee.h"

// Employee هنا قمنا بتحديد كيف سيتم إسناد القيم الأولية عند إنشاء كائن من الكلاس
// Employee و هو سيتولى أمر تخزينها في الخصائص التي ورثها الكلاس Person سيتم تمريرها لكونستكتور الكلاس gender و phone ,name القيم التي يتم تمريرها للباراميترات
// Employee سيتم إسنادها بشكل مباشر للخصائص التي تم تعريفها بداخل الكلاس workingTime و salary القيم التي يتم تمريرها مكان الباراميترين
Employee::Employee(string name, string phone, string gender, float salary, string workingTime)
: Person(name, phone, gender)
{
    this->salary = salary;
    this->workingTime = workingTime;
}

// Person التي تم وراثتها من الكلاس printExtraInfo() للدالة Override هنا كأننا فعلنا
// Employee عند استدعاء الدالة من كائن أصله من الكلاس workingTime و salary قمنا بتعريف هذه الدالة بهدف طباعة قيم الخصائص 
void Employee::printExtraInfo()
{
    cout << "Salary: " << this->salary << "$\n";
    cout << "Working time: " << this->workingTime << "\n";
}

Product.h
#ifndef PRODUCT_H
#define PRODUCT_H

#include <string>
using namespace std;

// الذي يمثل المنتج Product هنا قمنا بذكر الخصائص, الدوال و الكونستركتور الذي يحتويه الكلاس
class Product
{
    public:
        // هنا قمنا بتعريف الخصائص الأساسية التي يجب أن يملكها أي منتج
        int id;
        string name;
        float price;
        
        // هنا قمنا بتحديد شكل كونستركتور الكلاس و الذي سنستخدمه لإسناد قيم للكائن الذي ننشئه من هذا الكلاس بشكل مباشر        
        Product(string name, float price);

    private:
        // لأننا بنفس الوقت نريده أن يكون موحداً private و static قمنا بتعريفه كـ idIncrementer الثابت
        // لجميع الكائنات التي ننشئها من هذا الكلاس و لا يمكن التعامل معه بشكل مباشر من أي كلاس آخر
        static int idIncrementer;
};

#endif

Product.cpp
#include "Product.h"

// idIncrementer هنا قمنا بتحديد القيمة الأولية للثابت
int Product::idIncrementer = 0;

// Product هنا قمنا بتحديد كيف سيتم إسناد القيم الأولية عند إنشاء كائن من الكلاس
// id تزيد 1 في كل مرة و من ثم يتم وضعها في الخاصية idIncrementer لاحظ أننا جعلنا قيمة
// الخاصة بالكائن. القيم الأخرى التي سيتم تمريرها للكائن سيتم تخزينها بشكل مباشر في خصائص الكائن
Product::Product(string name, float price)
{
    idIncrementer++;
    this->id = idIncrementer;
    this->name = name;
    this->price = price;
}

Order.h
#ifndef ORDER_H
#define ORDER_H

// كل فاتورة ستضمن شخص (صاحب الفاتور) و مصفوفة من المنتجات لذلك قمنا بتضمين الكلاسات التالية
#include "Person.h"
#include "Product.h"
#include <vector>

// الذي يمثل المنتج Order هنا قمنا بذكر الخصائص, الدوال و الكونستركتور الذي يحتويه الكلاس
class Order
{
    public:
        // هنا قمنا بتعريف الخصائص الأساسية التي يجب أن يملكها أي منتج
        int id;
        string date;
        bool isPaid;
        Person *person;   // كل فاتورة ستملك مؤشر للشخص الذي يمثل صاحب الفاتورة
        vector<Product> products;   // كل فاتورة ستملك مصفوفة من المنتجات

        // هنا قمنا بتحديد شكل كونستركتور الكلاس و الذي سنستخدمه لإسناد قيم للكائن الذي ننشئه من هذا الكلاس بشكل مباشر        
        Order(string date, bool isPaid, Person *person, vector<Product> products);

    private:
        // لأننا بنفس الوقت نريده أن يكون موحداً private و static قمنا بتعريفه كـ idIncrementer المتغير
        // لجميع الكائنات التي ننشئها من هذا الكلاس و لا يمكن التعامل معه بشكل مباشر من أي كلاس آخر
        static int idIncrementer;
};

#endif

Order.cpp
#include "Order.h"

// idIncrementer هنا قمنا بتحديد القيمة الأولية للثابت
int Order::idIncrementer = 0;

// Order هنا قمنا بتحديد كيف سيتم إسناد القيم الأولية عند إنشاء كائن من الكلاس
// id تزيد 1 في كل مرة و من ثم يتم وضعها في الخاصية idIncrementer لاحظ أننا جعلنا قيمة
// الخاصة بالكائن. القيم الأخرى التي سيتم تمريرها للكائن سيتم تخزينها بشكل مباشر في خصائص الكائن
Order::Order(string date, bool isPaid, Person* person, vector<Product> products)
{
    idIncrementer++;
    this->id = idIncrementer;
    this->date = date;
    this->isPaid = isPaid;
    this->person = person;
    this->products = products;
}

Company.h
#ifndef COMPANY_H
#define COMPANY_H

// Product و Employee ,Client ,Person حتى نستطيع التعامل معه و مع جميع الكلاسات التي يتضمنها, أي مع Order.h قمنا بتضمين الملف
#include "Order.h"

// يمثل كل ما تحتويه الشركة من أشخاص و منتجات و فواتير و الدوال التي يمكن استخدامها للتعامل معهم Company الكلاس
class Company
{
    public:
        vector<Person*> persons;   // سنضع فيه كل الأشخاص الذين ننشئهم persons الكائن
        vector<Product> products;  // سنضع فيه كل المنتجات التي ننشئها products الكائن
        vector<Order> orders;      // سنضع فيه كل الفواتير التي ننشئها products الكائن
        
        void addProduct(const Product& product);
        void addPerson(Person* person);
        void addOrder(const Order& Order);
        void removeProduct(int id);
        void removePerson(int id);
        void removeOrder(int id);
        void printPersonInfo(int id);
        void printProductDetails(int id);
        void printOrderDetails(int id);
        void printPersonOrders(int id);
};

#endif

Company.cpp
#include "Company.h"
#include <iostream>

vector<Person*> persons;
vector<Product> products;
vector<Order> orders;

// products بداخل المصفوفة product يمكن استخدامها لإضافة كائن من الكلاس addProduct() الدالة
void Company::addProduct(const Product& product)
{
    products.push_back(product);
}

// persons بداخل المصفوفة Persons يمكن استخدامها لإضافة مؤشر كائن من الكلاس addPerson() الدالة
void Company::addPerson(Person *person)
{
    persons.push_back(person);
}

// orders بداخل المصفوفة Order يمكن استخدامها لإضافة كائن من الكلاس addOrder() الدالة
void Company::addOrder(const Order& order)
{
    orders.push_back(order);
}

// الخاص به id بالإعتماد على رقم الـ products موضوع بداخل المصفوفة Product يمكن استخدامها لإلغاء كائن من الكلاس removeProduct() الدالة
void Company::removeProduct(int id)
{
    // products بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
    for (unsigned i = 0; i < products.size(); i++)
    {
        // الذي مررناه للدالة سيتم حذفه و من ثم الخروج من الدالة id الحالي يملك نفس رقم الـ products[i] في حال كان الكائن
        if (products[i].id == id)
        {
            products.erase(products.begin() + i);
            return;
        }
    }
    // الذي تم تمريره للدالة سيتم طباعة الجملة التالية id يملك نفس رقم الـ products في حال لم يتم إيجاد أي كائن في المصفوفة
    cout << "Product with id " << id << " is not found!\n";
    cout << "----------------------\n";
}

// الخاص به id بالإعتماد على رقم الـ persons أو من أحد الكلاسات التي ترث منه و موضوع بداخل المصفوفة Person يمكن استخدامها لإلغاء مؤشر كائن من الكلاس removePerson() الدالة
void Company::removePerson(int id)
{
    // persons بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
    for (unsigned i = 0; i < persons.size(); i++)
    {
        // الذي مررناه للدالة سيتم حذفه و من ثم الخروج من الدالة id الحالي يملك نفس رقم الـ persons[i] في حال كان الكائن
        if (persons[i]->id == id)
        {
            persons.erase(persons.begin() + i);
            return;
        }
    }
    // الذي تم تمريره للدالة سيتم طباعة الجملة التالية id يملك نفس رقم الـ persons في حال لم يتم إيجاد أي كائن في المصفوفة
    cout << "Person with id " << id << " is not found!\n";
    cout << "----------------------\n";
}

// الخاص به id بالإعتماد على رقم الـ orders موضوع بداخل المصفوفة Order يمكن استخدامها لإلغاء كائن من الكلاس removeOrder() الدالة
void Company::removeOrder(int id)
{
    // orders بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
    for (unsigned i = 0; i < orders.size(); i++)
    {
        // الذي مررناه للدالة سيتم حذفه و من ثم الخروج من الدالة id الحالي يملك نفس رقم الـ orders[i] في حال كان الكائن
        if (orders[i].id == id)
        {
            orders.erase(orders.begin() + i);
            return;
        }
    }
    // الذي تم تمريره للدالة سيتم طباعة الجملة التالية id يملك نفس رقم الـ orders في حال لم يتم إيجاد أي كائن في المصفوفة
    cout << "Order with id " << id << " is not found!\n";
    cout << "----------------------\n";
}

// الخاص به id بالإعتماد على رقم الـ persons يمكن استخدامها لطباعة كل المعلومات المتوفرة حول شخص موضوع مؤشره بداخل المصفوفة printPersonInfo() الدالة
void Company::printPersonInfo(int id)
{
    // persons بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
    for (unsigned i = 0; i < persons.size(); i++)
    {
        // الذي مررناه للدالة سيتم طباعة كل معلوماته و من ثم الخروج من الدالة id الحالي يملك نفس رقم الـ persons[i] في حال كان الكائن
        if (persons[i]->id == id)
        {
            cout << "Person with id " << id << " info.\n";
            cout << "Name: " << persons[i]->name << "\n";
            cout << "Phone: " << persons[i]->phone << "\n";
            cout << "Gender: " << persons[i]->gender << "\n";

            // لطباعة المعلومات الإضافية المتوفرة عن الشخص printExtraInfo() هنا قمنا باستدعاء الدالة
            // Client الموجودة في الكلاس printExtraInfo() سيتم إستدعاء الدالة Client إذا كان الشخص عبارة عن كائن أصله من الكلاس
            // Employee الموجودة في الكلاس printExtraInfo() سيتم إستدعاء الدالة Employee إذا كان الشخص عبارة عن كائن أصله من الكلاس
            persons[i]->printExtraInfo();

            cout << "----------------------\n";
            return;
        }
    }
    // الذي تم تمريره للدالة سيتم طباعة الجملة التالية id يملك نفس رقم الـ persons في حال لم يتم إيجاد أي كائن في المصفوفة
    cout << "Person with id " << id << " is not found!\n";
    cout << "----------------------\n";
}

// الخاص به id بالإعتماد على رقم الـ products يمكن استخدامها لطباعة كل المعلومات المتوفرة حول منتج موضوع بداخل المصفوفة printProductDetails() الدالة
void Company::printProductDetails(int id)
{
    // products بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
    for (unsigned i = 0; i < products.size(); i++)
    {
        // الذي مررناه للدالة سيتم طباعة كل معلوماته و من ثم الخروج من الدالة id الحالي يملك نفس رقم الـ products[i] في حال كان الكائن
        if (products[i].id == id)
        {
            cout << "Product with id " << id << " details.\n";
            cout << "Name: " << products[i].name << "\n";
            cout << "Price: " << products[i].price << "$\n";
            cout << "----------------------\n";
            return;
        }
    }
    // الذي تم تمريره للدالة سيتم طباعة الجملة التالية id يملك نفس رقم الـ products في حال لم يتم إيجاد أي كائن في المصفوفة
    cout << "Product with id " << id << " is not found!\n";
    cout << "----------------------\n";
}

// الخاص به id بالإعتماد على رقم الـ orders يمكن استخدامها لطباعة كل المعلومات المتوفرة حول فاتورة موضوعة بداخل المصفوفة printOrderDetails() الدالة
void Company::printOrderDetails(int id)
{
    // سنستخدمه لحساب ناتج جمع جميع أسعار المنتجات التي نجدها في الفاتورة totalSum المتغير
    float totalSum = 0;

    // orders بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
    for (unsigned i = 0; i < orders.size(); i++)
    {
        // الذي مررناه للدالة سيتم طباعة كل معلوماته و من ثم الخروج من الدالة id الحالي يملك نفس رقم الـ orders[i] في حال كان الكائن
        if (orders[i].id == id)
        {
            cout << "Order with id " << id << " details.\n";
            cout << "Date: " << orders[i].date << "\n";
            cout << "Is paid: " << ((orders[i].isPaid)? "Yes": "no") << "\n";
            cout << "Ordered by: " << orders[i].person->name << "\n";
            cout << "Products:\n";

            // orders[i] التي تملكها الفاتورة products بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
            // و سنطبع إسمه و سعره totalSum كل منتج نمر عليه, سنقوم بإضافة ثمنه على قيمة المتغير
            for (unsigned j = 0; j < orders[i].products.size(); j++)
            {
                totalSum += orders[i].products[j].price;
                cout << "- " << orders[i].products[j].name << ": " << orders[i].products[j].price << "$\n";
            }
            
            // بعد أن يتم حساب ناتج جمع جميع أسعار المنتجات الموضوعة في الفاتورة سيتم عرض الناتج و من ثم الخروج من الدالة
            cout << "Total: " << totalSum << "$\n";
            cout << "----------------------\n";
            return;
        }
    }
    // الذي تم تمريره للدالة سيتم طباعة الجملة التالية id يملك نفس رقم الـ orders في حال لم يتم إيجاد أي كائن في المصفوفة
    cout << "Order with id " << id << " is not found!\n";
    cout << "----------------------\n";
}

// الخاص به id بالإعتماد على رقم الـ orders يمكن استخدامها لطباعة كل المعلومات المتوفرة حول فواتير شخص موضوع بداخل المصفوفة printPersonOrders() الدالة
void Company::printPersonOrders(int id)
{
    // persons بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
    for (unsigned i = 0; i < persons.size(); i++)
    {
        // الذي مررناه للدالة سيتم المرور على جميع فواتيره id الحالي يملك نفس رقم الـ persons[i] في حال كان الكائن
        if (persons[i]->id == id)
        {
            cout << "All orders made by person with id " << id << ":\n";

            // orders بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
            for (unsigned j = 0; j < orders.size(); j++)
            {
                // الذي مررناه للدالة سيتم طباعة كل معلوماته و من ثم الخروج من الدالة  id الحالي يملك نفس رقم الـ orders[i] في حال كان الكائن
                if (orders[j].person->id == id)
                {
                    cout << "> Order with id " << id << " details.\n";
                    cout << "  Date: " << orders[j].date << "\n";
                    cout << "  Is paid: " << ((orders[j].isPaid)? "Yes": "no") << "\n";
                    cout << "  Ordered by: " << orders[j].person->name << "\n";
                    cout << "  Products:\n";

                    // سنستخدمه لحساب ناتج جمع جميع أسعار المنتجات التي نجدها في كل فاتورة totalSum المتغير
                    float totalSum = 0;

                    // orders[j] التي تملكها الفاتورة products بواسطة هذه الحلقة سنمر على جميع الكائنات المخزنة بداخل المصفوفة
                    // و سنطبع إسمه و سعره totalSum كل منتج نمر عليه, سنقوم بإضافة ثمنه على قيمة المتغير
                    for (unsigned k = 0; k < orders[j].products.size(); k++)
                    {
                        totalSum += orders[j].products[k].price;
                        cout << "- " << orders[j].products[k].name << ": " << orders[j].products[k].price << "$\n";
                    }

                    // بعد أن يتم حساب ناتج جمع جميع أسعار المنتجات الموضوعة في الفاتورة سيتم عرض الناتج
                    cout << "Total: " << totalSum << "$\n";
                }
            }

            // بعد طباعة جميع الفواتير سيتم الخروج من الدالة
            cout << "----------------------\n";
            return;
        }
    }

    // الذي تم تمريره للدالة سيتم طباعة الجملة التالية id يملك نفس رقم الـ authors في حال لم يتم إيجاد أي كائن في المصفوفة
    cout << "Person with id " << id << " is not found!\n";
    cout << "----------------------\n";
}

main.cpp
#include <iostream>
#include "Client.h"
#include "Employee.h"
#include "Product.h"
#include "Order.h"
#include "Company.h"
#include <vector>

using namespace std;

int main()
{
    // أي كأننا قمنا بإنشاء شخصين Person هنا قمنا بإنشاء كائنين من كلاسات ترث من الكلاس
    // و بالتالي فإنه يمثل شخص يعتبر زبون Client عبارة عن كائن من الكلاس person1
    // و بالتالي فإنه يمثل شخص يعتبر موظف Employee عبارة عن كائن من الكلاس person2
    Client person1("Mhamad", "+96170123456", "Male", "mhamad@example.com");
    Employee person2("Nadine", "+9631249392", "Female", 800, "8:00 AM to 3:00 PM");

    // company الموجودة في الكائن persons لأننا ننوي تمريرهم بعد قليل للمصفوفة person2 و مؤشر للكائن person1 هنا قمنا بإنشاء مؤشر للكائن
    Client *person1_pointer = &person1;
    Employee *person2_pointer = &person2;

    // و التي تمثل 6 منتجات Product هنا قمنا بتعريف 6 كائنات من الكلاس
    Product product1 = Product("Keyboard", 15);
    Product product2 = Product("Camera", 45);
    Product product3 = Product("HDD 1TB", 70);
    Product product4 = Product("SSD 1TB", 274.66);
    Product product5 = Product("Mouse", 8);
    Product product6 = Product("Table", 44.55);

    // product3 و product2 و product1 وضعنا فيه الكائنات vector هنا قمنا بتعريف كائن من الكلاس
    // و الذي سننئه بعد قليل order1 لأننا ننوي وضعها في مصفوفة المنتجات التي تم شراءها في الفاتورة التي يمثلها الكائن
    vector<Product> order1Products;
    order1Products.push_back(product1);
    order1Products.push_back(product2);
    order1Products.push_back(product3);

    // product4 وضعنا فيه الكائن vector هنا قمنا بتعريف كائن من الكلاس
    // و الذي سننئه بعد قليل order2 لأننا ننوي وضعه في مصفوفة المنتجات التي تم شراءها في الفاتورة التي يمثلها الكائن
    vector<Product> order2Products;
    order2Products.push_back(product4);

    // product5 و product6 وضعنا فيه الكائنات vector هنا قمنا بتعريف كائن من الكلاس
    // و الذي سننئه بعد قليل order3 لأننا ننوي وضعها في مصفوفة المنتجات التي تم شراءها في الفاتورة التي يمثلها الكائن
    vector<Product> order3Products;
    order3Products.push_back(product5);
    order3Products.push_back(product6);

    // و التي تمثل فواتير Order هنا قمنا بتعريف 3 كائنات من الكلاس
    // person1 وضعناهما لنفس الشخص الذي يمثله مؤشر الكائن order2 و order1 لاحظ أن الفاتورتين
    Order order1 = Order("2020-1-1", true, person1_pointer, order1Products);
    Order order2 = Order("2020-2-7", true, person1_pointer, order2Products);
    Order order3 = Order("2020-5-4", false, person2_pointer, order3Products);

    // لأننا نريد تخزين الأشخاص و المنتجات و الفواتير بشكل مرتب بداخله Company هنا قمنا بإنشاء كائن من الكلاس
    Company company = Company();

    // addPerson() بواسطة الدالة company التي يمكلها الكائن persons هنا قمنا بإضافة الشخصين من خلال مؤشراتهم في المصفوفة
    company.addPerson(person1_pointer);
    company.addPerson(person2_pointer);

    // addProduct() بواسطة الدالة company التي يمكلها الكائن products هنا قمنا بإضافة المنتجات في المصفوفة
    company.addProduct(product1);
    company.addProduct(product2);
    company.addProduct(product3);
    company.addProduct(product4);
    company.addProduct(product5);
    company.addProduct(product6);

    // addOrder() بواسطة الدالة company التي يمكلها الكائن orders هنا قمنا بإضافة الفواتير في المصفوفة
    company.addOrder(order1);
    company.addOrder(order2);
    company.addOrder(order3);

    // printPersonInfo() الخاص بهم و بواسطة الدالة id هنا قمنا بطباعة معلومات كلا الشخصين بالإعتماد على رقم التعرفة
    // تذكر: رقم التعرفة الخاص بكل شخص تم إنشاؤه بشكل تلقائي عند إنشاء كل شخص بداخل الكونستركتور
    company.printPersonInfo(1);
    company.printPersonInfo(2);

    // printProductDetails() الخاص بهم و بواسطة الدالة id هنا قمنا بطباعة معلومات كل المنتجات بالإعتماد على رقم التعرفة
    // تذكر: رقم التعرفة الخاص بكل منتج تم إنشاؤه بشكل تلقائي عند إنشاء كل منتج بداخل الكونستركتور
    company.printProductDetails(1);
    company.printProductDetails(2);
    company.printProductDetails(3);
    company.printProductDetails(4);
    company.printProductDetails(5);
    company.printProductDetails(6);

    // printPersonOrders() الخاص بهم و بواسطة الدالة id هنا قمنا بطباعة الفواتير التي يملكها كل شخص بالإعتماد على رقم التعرفة
    company.printPersonOrders(1);
    company.printPersonOrders(2);

    // removeOrder() هنا قمنا الفاتورة التي تملك رقم التعرفة 1 بواسطة الدالة
    // printOrderDetails() بعدها حاولنا طباعة معلومات الفاتورة التي قمنا بحذفها بواسطة الدالة
    // بعدها قمنا بطباعة جمبع الفواتير التي يمكلها الشخص الذي يملك رقم التعرفة 1 و الذي كان يملك الفاتورة التي تم حذفها
    // لاحظ أن الفاتورة المحذوفة أيضاَ لم تظر ضمن فواتيره
    company.removeOrder(1);
    company.printOrderDetails(1);
    company.printPersonOrders(1);

    return 0;
}

سنحصل على النتيجة التالية عند التشغيل.

Person with id 1 info.   --> الموضوعة في السطر 77 printPersonInfo() تم عرض هذا المحتوى بسبب استدعاء الدالة
Name: Mhamad
Phone: +96170123456
Gender: Male
Email: mhamad@example.com
----------------------
Person with id 2 info.   --> الموضوعة في السطر 78 printPersonInfo() تم عرض هذا المحتوى بسبب استدعاء الدالة
Name: Nadine
Phone: +9631249392
Gender: Female
Salary: 800.0$
Working time: 8:00 AM to 3:00 PM
----------------------
Product with id 1 details.   --> الموضوعة في السطر 82 printProductDetails() تم عرض هذا المحتوى بسبب استدعاء الدالة
Name: Keyboard
Price: 15.0$
----------------------
Product with id 2 details.   --> الموضوعة في السطر 83 printProductDetails() تم عرض هذا المحتوى بسبب استدعاء الدالة
Name: Camera
Price: 45.0$
----------------------
Product with id 3 details.   --> الموضوعة في السطر 84 printProductDetails() تم عرض هذا المحتوى بسبب استدعاء الدالة
Name: HDD 1TB
Price: 70.0$
----------------------
Product with id 4 details.   --> الموضوعة في السطر 85 printProductDetails() تم عرض هذا المحتوى بسبب استدعاء الدالة
Name: SSD 1TB
Price: 274.66$
----------------------
Product with id 5 details.   --> الموضوعة في السطر 86 printProductDetails() تم عرض هذا المحتوى بسبب استدعاء الدالة
Name: Mouse
Price: 8.0$
----------------------
Product with id 6 details.   --> الموضوعة في السطر 87 printProductDetails() تم عرض هذا المحتوى بسبب استدعاء الدالة
Name: Table
Price: 44.55$
----------------------
All orders made by person with id 1:   --> الموضوعة في السطر 90 printPersonOrders() تم عرض هذا المحتوى بسبب استدعاء الدالة
> Order: #1
  Date: 2020-1-1
  Is paid: yes
  Ordered by: Mhamad
  Products:
  - Keyboard: 15.0$
  - Camera: 45.0$
  - HDD 1TB: 70.0$
  Total Price: 130.0$
> Order: #2
  Date: 2020-2-7
  Is paid: yes
  Ordered by: Mhamad
  Products:
  - SSD 1TB: 274.66$
  Total Price: 274.66$
----------------------
All orders made by person with id 2:   --> الموضوعة في السطر 91 printPersonOrders() تم عرض هذا المحتوى بسبب استدعاء الدالة
> Order: #3
  Date: 2020-5-4
  Is paid: no
  Ordered by: Nadine
  Products:
  - Mouse: 8.0$
  - Table: 44.55$
  Total Price: 52.55$
----------------------
Order with id 1 is not found!   --> الموضوعة في السطر 98 printOrderDetails() تم عرض هذا المحتوى بسبب استدعاء الدالة
----------------------
All orders made by person with id 1:   --> الموضوعة في السطر 99 printPersonInfo() تم عرض هذا المحتوى بسبب استدعاء الدالة
> Order: #2
  Date: 2020-2-7
  Is paid: yes
  Ordered by: Mhamad
  Products:
  - SSD 1TB: 274.66$
  Total Price: 274.66$
----------------------