تحديات برمجيةالتحدي الثاني - الحل بلغة 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
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; };
// 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 هنا قمنا بذكر الخصائص, الدوال و الكونستركتور الذي يحتويه الكلاس // 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(); };
// 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 هنا قمنا بذكر الخصائص, الدوال و الكونستركتور الذي يحتويه الكلاس // 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(); };
// 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"; }
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; };
// 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 هنا قمنا بذكر الخصائص, الدوال و الكونستركتور الذي يحتويه الكلاس 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; };
// 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; }
// Product و Employee ,Client ,Person حتى نستطيع التعامل معه و مع جميع الكلاسات التي يتضمنها, أي مع 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); };
// 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"; }vector<Person*> persons; vector<Product> products; vector<Order> orders;
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; }
سنحصل على النتيجة التالية عند التشغيل.
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$
----------------------