![ישן](https://static.fresh.co.il/images/vBulletin/statusicon/post_old.gif)
22-03-2010, 00:12
|
|
|
חבר מתאריך: 30.07.05
הודעות: 949
|
|
כעקרון כן - קוד של C אמור להתקמפל עם מהדר ++C עם כמות שינויים מינימאלית, אז לשאלה אם זה אפשרי התשובה היא: כן
אבל ניתן לשאול גם שאלה נגדית: למה לך לעשות דבר כזה?
איזה יתרון את רואה בשימוש ב-void* על פני שימוש בפולימורפיזם (שנובע מירושה) ו-templates?
כעקרון את צריכה משהו כזה:
קוד PHP:
class generic_list { public: // Definitions typedef void* element; public: // Interface generic_list() : head(NULL), tail(NULL), iterator(NULL), size(0) {}
~generic_list() { while(!Node::IsFinished(head)) { Node *help = head; head = head->GetNext(); delete help; } }
void push_back(element d) { Node *n = new Node(d, NULL, tail); tail = n; if (head == NULL) { // First element in the list head = tail; } ++size; }
void push_front(element d) { Node *n = new Node(d, head, NULL); head = n; if (tail == NULL) { // First element in the list tail = head; } ++size; }
const element IterateFromStart() { iterator = head; return GetCurrent(); }
const element IterateFromEnd() { iterator = tail; return GetCurrent(); }
const element GetCurrent() const { if (!Node::IsFinished(iterator)) { return iterator->GetData(); } else { return NULL; // In proper implementation - a throw would be better... } }
bool IterateNext() { if (!Node::IsFinished(iterator)) { iterator = iterator->GetNext(); return true; } else { // In proper implementation, a throw for else would be in order... return false; } }
bool IteratePrev() { if (!Node::IsFinished(iterator)) { iterator = iterator->GetPrev(); return true; } else { // In proper implementation, a throw for else would be in order... return false; } }
bool IteratorDone() const { return Node::IsFinished(iterator); }
void InsertAfterCurr(element d) { iterator->InsertNext(d); }
void InsertBeforeCurr(element d) { iterator->InsertPrev(d); }
void DeleteCurr(bool next = true) // the input means the direction to advance - next or prev { if (Node::IsFinished(iterator)) { // No point in doing anything if finished... return; // Or throw, for proper implementation } if (iterator == head) head = iterator->GetNext(); if (iterator == tail) tail = iterator->GetPrev(); Node *help = iterator; iterator = (next) ? iterator->GetNext() : iterator->GetPrev(); delete help; --size; } private: // Helper classes class Node { public: // Interface Node(element d, Node *n = NULL, Node *p = NULL) : data(d), next(n), prev(p) { }
~Node() { if (prev) { // If prev not NULL => there is a previous node prev->next = next; // maintain connection } if (next) { // If next not NULL => there is a next node next->prev = prev; // maintain connection } if (data) delete data; // If data isn't NULL => release resources }
const element GetData() const { return data; } Node *GetNext() const { return this->next); }
Node *GetPrev() const { return this->prev); }
void InsertNext(element data) { Node *n = new Node(data, this->next, this); this->next = n; }
void InsertPrev(element data) { Node *n = new Node(data, this, this->prev); this->prev = n; }
static bool IsFinished(Node *node) { return (node == NULL); } private: // Members element data; Node *next; Node *prev; }; private: // Members Node *head; Node *tail; Node *iterator; size_t size; };
כמה הערות:
1) מדובר במימוש מאד בסיסי... את יכולה להשתמש בחלקים מהקוד, או סתם לקבל ממנו רעיונות... כמובן שכל הרחבה מכאן - על אחריותך...
2) הקוד נכתב בכתבן - הוא לא נוסה ולא קומפל... יתכן שיש באגים ואפילו שגיאות קומפילציה - אבל הקוד נועד רק כדוגמא בכל מקרה אז אני מקווה שתסלחי לי על זה ![Smile](images/smilies/smile.gif)
3) כמובן שרצוי לחלק את הקוד לקובץ h. שיכיל רק את ההצהרות וקובץ cpp. שיכיל את המימושים, אבל בדיוק כמו 2 - זה רק קוד לדוגמא...
_____________________________________
חתימתכם הוסרה כיוון שלא עמדה בחוקי האתר. לפרטים נוספים לחצו כאן. תוכלו לקבל עזרה להתאמת החתימה לחוקים בפורום חתימות וצלמיות.
נערך לאחרונה ע"י Dark Knight בתאריך 22-03-2010 בשעה 00:16.
|