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) הקוד נכתב בכתבן - הוא לא נוסה ולא קומפל... יתכן שיש באגים ואפילו שגיאות קומפילציה - אבל הקוד נועד רק כדוגמא בכל מקרה אז אני מקווה שתסלחי לי על זה
3) כמובן שרצוי לחלק את הקוד לקובץ h. שיכיל רק את ההצהרות וקובץ cpp. שיכיל את המימושים, אבל בדיוק כמו 2 - זה רק קוד לדוגמא...
_____________________________________
חתימתכם הוסרה כיוון שלא עמדה בחוקי האתר. לפרטים נוספים לחצו כאן. תוכלו לקבל עזרה להתאמת החתימה לחוקים בפורום חתימות וצלמיות.
נערך לאחרונה ע"י Dark Knight בתאריך 22-03-2010 בשעה 00:16.
|