1 / 24

Classes with dynamic objects

List as a (dynamic) class. Classes with dynamic objects. ‘Class’ matters!. global. local. public. class A { public int x; void f(); } main() { A a; a.x = 0; a.f(); }. int x; void f() { int x; x=10; } main() { x=0; f(); }. int x; void f() { x=10; } main() {

desma
Télécharger la présentation

Classes with dynamic objects

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. List as a (dynamic) class Classes with dynamic objects

  2. ‘Class’ matters! global local public class A { public int x; void f(); } main() { A a; a.x = 0; a.f(); } int x; void f() { int x; x=10; } main() { x=0; f(); } int x; void f() { x=10; } main() { x=0; f(); }

  3. Public or private? class A { public: void f(); int x; private: int y; } void A::f() { x=10; y=100; } int main() { A a; a.f(); cout << a.x << endl; cout << a.y << endl; // no!!! a.x = 1000; a.y = 10000; // no!!! }

  4. Abstract Data Type: public function, private data class A { public: A(); int f(); private: int x; } A::A() { x=0; } int A::f() { return x; } int main() { A a; cout << a.f(); // not a.x!!! A b(a); A c; c = a; // member-wise copy } Objects are calling member funtions (public interface) Member functions are using member variables (private data) Objects are not directly dependent on implementation (private data)

  5. Static and dynamic Static variables (objects) Dynamic variables (objects) A (direct) named memory location A static part (pointer) + (indirect) nameless memory location (dynamic part) int a; a = 20; int* pa; pa = new int; *pa = 20; 20 20 a pa dynamic static static

  6. classes At least one pointer variable (I.e. dynamic variable) Only static member variables class B { public: B(); B(const B& b); ~B(); private: int* px; } class A { public: A(); private: int x; } (Must) a defaut value constructor A() for ‘copy constructor’ automatically privided No destructor ‘assignment’ automatically provided (Must) a defaut value constructor for (Must) redefine ‘copy constructor’ (Must) the destructor (Must) redefine ‘assignment’ (do later) Creation by new + initialiation initialisation

  7. B::B() { px = new int; *px = 0; } B::B(const B& b) { px = new int; (*px) = *(b.px); } B::~B() { delete px; } class B { public: B(); B(const B& b); ~B(); private: int* px; }

  8. Automatic behavior of constructors/destructor All constructors/destructor have automatic behavior, they are called ‘implicitly’!!! (that’s why they have standard names!) Constructors are called when creating variables and other occasions: A a; // implicitly call the default value constructor A::A(); A b(a); // implicitly call the copy constructor A::A(const A& a); Destructors are called when the variables go out of scope void somefunction() { B b; };

  9. Example of a (dynamic) class: linked list class

  10. linked lists: definition struct Node{ int data; Node* next; }; typedef Node* NodePtr; NodePtr head; bool listEmpty(NodePtr head) { } int getHead(NodePtr head) { } NodePtr getRest(NodePtr head) { } NodePtr addHead(NodePtr head, int newdata) { } void delHead(NodePtr& Head){ }

  11. Usage: void main(){ NodePtr Head1=NULL, Head2 = NULL, Head; addHead(Head1, 50); addHead(Head1, 40); addHead(Head1, 30); addHead(Head1, 20); cout << "List 1: " << endl; DisplayList(Head1); cout << "Length of Head1 list: " << length(Head1) << endl; cout << "Recursive length of Head1 list: " << lengthRec(Head1) << endl; if(isPalindrome(Head1)) cout << "Head1 list is palindrome" << endl; else cout << "Head1 list is not palindrome" << endl; addHead(Head2, 25); addHead(Head2, 35); addHead(Head2, 45); addHead(Head2, 35); addHead(Head2, 25); cout << "List 2: " << endl; DisplayList(Head2); cout << "Length of Head2 list: " << length(Head2) << endl; cout << "Recursive length of Head2 list: " << lengthRec(Head2) << endl; if(isPalindrome(Head2)) cout << "Head2 list is palindrome" << endl; else cout << "Head2 list is not palindrome" << endl; Head = mergeLists(Head1, Head2); cout << "Merged List: " << endl; DisplayList(Head); cout << "Length of Merged list: " << length(Head) << endl; cout << "Recursive length of Merged list: " << lengthRec(Head) << endl; if(isPalindromeRec(Head)) cout << "Merged list is palindrome" << endl; else cout << "Merged list is not palindrome" << endl; cout << "check the list again:" << endl; DisplayList(Head); }

  12. Make an Abstract Data Type • One more example of ADT: • integer linked list using class • A class with dynamic objects: • Copy constructor • Destructor

  13. ‘new’ member functions struct Node{ public: int data; Node* next; }; typedef Node* Nodeptr; class list { public: list(); // constructor list(const list& list1); // copy constructor ~list(); // destructor bool empty() const; // boolean function int headElement() const; // access functions void addHead(int newdata); // add to the head void deleteHead(); // delete the head int length() const; // utility function void print() const; // output private: Nodeptr head; }; ‘old’ operations

  14. How to use it void main(){ list L; // constructor called automatically here for L L.print(); { } L.addHead(30); L.print(); { 30 } L.addHead(13); L.print(); { 13 30 } L.addHead(40); L.print(); { 40 13 30 } L.addHead(50); L.print(); { 50 40 13 30 } list N(L); N.print(); { 50 40 13 30 } list R; R.print(); { } if(R.empty()) cout << "List R empty" << endl; L.deleteHead(); L.print(); { 40 13 30 } L.deleteHead(); L.print(); { 13 30 } if(L.empty()) cout << "List L empty" << endl; else{ cout << "List L contains " << L.length() << " nodes" << endl; cout << "Head element of list L is: " << L.headElement() << endl; } } // destructor called automatically here for L

  15. Implementation Some simple member functions: list::list(){ head = NULL; } bool list::empty() const{ if(head==NULL) return true; else return false; } int list::headElement() const { if(head != NULL) return head->data; else{ cout << "error: trying to find head of empty list" << endl; exit(1); } }

  16. (explicitly defined) copy constructor: list::list(const list& list1) { head = NULL; Nodeptr cur = list1.head; while(cur != NULL) { // addEnd(cur->data); addHead(cur->data); // inverse list order cur = cur->next; } }

  17. Destructor: deallocation function list::~list(){ Nodeptr cur; while(head!=NULL){ cur = head; head = head->next; delete cur; } }

  18. Adding an element to the head: void list::addHead(int newdata){ Nodeptr newPtr = new Node; newPtr->data = newdata; newPtr->next = head; head = newPtr; }

  19. Deleting the head: void list::deleteHead(){ if(head != NULL){ Nodeptr cur = head; head = head->next; delete cur; } }

  20. Print the list: void list::print() const{ cout << "{"; Nodeptr cur = head; while(cur != NULL){ cout << cur->data << " "; cur = cur->next; } cout << "}" << endl; }

  21. Computing the number of elements of a given list: int list::length() const{ int n=0; Nodeptr cur = head; while(cur != NULL){ n++; cur = cur->next; } return n; }

  22. struct Node{ public: int data; Node* next; }; typedef Node* Nodeptr; class list { public: list(); // constructor list(const list& list1); // copy constructor const list& operator=(const list& list1); // assigment, l = l1; ~list(); // destructor bool empty() const; // boolean function int head() const; // access functions list remaining() const; // the list with the head removed void insert(int d); // insertion void delete(int d); // deletion int length() const; // utility function void print() const; // private: Nodeptr head; }; Interface functions An almost ideal list class

  23. copy constructor: list::list(const listClass& list1) { head = NULL; Nodeptr cur = list1.head; while(cur != NULL) { // addEnd(cur->data); addHead(cur->data); // inverse list order cur = cur->next; } } Operator assignment, ‘deep copy’ Const list& operator=(const list& list1) { if (this != &list1) { head = NULL; Nodeptr cur = list1.head; while(cur != NULL) { // addEnd(cur->data); addHead(cur->data); // inverse list order cur = cur->next; } return *this; } Delete[] head; Big three: copy constructor, operator=, destructor

  24. Usage difference node* head1, head2; head1 = NULL; head2 = NULL addEnd(head1,5); node* head3 = NULL; copylist(head1, head3); head3 = head2; list l1, l2; l1.addEnd(5); list l3(l1); l3 = l2;

More Related