Download presentation
Presentation is loading. Please wait.
1
Classes with dynamic members
2
‘Class’ matters! global local public class A { int x; public int x;
void f(); } main() { A a; a.x = 0; a.f(); int x; void f() { x=10; } main() { x=0; f(); int x; void f() { x=10; } main() { x=0; f(); Unstructured with everything ‘global’ Structured with ‘local’ variables, ‘global’ functions Object-oriented with ‘global’ objects
3
Public or private? class A { int main() { public: A a; void f();
a.f(); cout << a.x << endl; cout << a.y << endl; // no!!! a.x = 1000; a.y = 10000; // no!!! } class A { public: void f(); int x; private: int y; } void A::f() { x=10; y=100; Global objects member functions (global? or public to objects) member variables (local or private to member functions)
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 static dynamic static
6
At least one pointer member (I.e. dynamic variable)
classes At least one pointer member (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) = *(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
A constructor is called when: declare/define objects pass by value
return by value X f(X x) { X a; return a; }
10
A function returning an object
X f() { X x; return x; } ‘return x’ returns a temporay object ‘temp’ of class X by constructor (because x is a local object, and to be ‘destructed’ !)
11
Make an Abstract Data Type with ‘dynamic’ class
One more example of ADT: integer linked list using class A class with dynamic objects: Copy constructor Destructor
12
linked lists: definition
struct Node{ int data; Node* next; }; Node* head; bool listEmpty(Node* head) { } Node* addHead(Node* head, int newdata) { int getHead(Node* head) { Node* getRest(Node* head) { // void delHead(Node*& Head){ // }
13
Usage in ‘procedural way’:
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); 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; 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; cout << "Merged list is not palindrome" << endl; cout << "check the list again:" << endl; }
14
‘new’ member functions
struct Node{ public: int data; Node* next; }; class listClass { listClass(); // constructor listClass(const listClass& list1); // copy constructor ~listClass(); // destructor bool empty() const; // boolean function void addHead(int newdata); // add to the head void delHead(); // delete the head int headElement() const; // access functions int length() const; // utility function void print() const; // output private: Node* head; ‘new’ member functions ‘old’ operations
15
Usage in ‘object way’: void main(){
listClass L; // constructor called automatically here for L L.print(); { } L.addHead(30); L.print(); { 30 } L.addHead(13); L.print(); { } L.addHead(40); L.print(); { } L.addHead(50); L.print(); { } listClass N(L); N.print(); { } listClass R; R.print(); { } if(R.empty()) cout << "List R empty" << endl; L.delHead(); 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
16
Some simple member functions:
Implementation Some simple member functions: listClass::listClass() { head = NULL; } bool listClass::empty() const { if(head==NULL) return true; else return false; int listClass::headElement() const { if(head != NULL) return head->data; else{ cout << "error: trying to find head of empty list" << endl; exit(1);
17
(explicitly defined) copy constructor:
listClass::listClass(const listClass& list1) { head = NULL; Node* cur = list1.head; while(cur != NULL) { // addEnd(cur->data); addHead(cur->data); // inverse list order cur = cur->next; } Call other member function!, so within ‘class’, still ‘procedural’.
18
Destructor: deallocation function
listClass::~listClass() { Node* cur; while(head!=NULL){ cur = head; head = head->next; delete cur; }
19
Adding an element to the head:
void listClass::addHead(int newdata) { Node* newPtr = new Node; newPtr->data = newdata; newPtr->next = head; head = newPtr; }
20
Deleting the head: void listClass::delHead() { if(head != NULL){
Node* cur = head; head = head->next; delete cur; }
21
Print the list: void listClass::print() const { cout << "{";
Node* cur = head; while(cur != NULL){ cout << cur->data << " "; cur = cur->next; } cout << "}" << endl;
22
Computing the number of elements of a given list:
int listClass::length() const { int n=0; Node* cur = head; while(cur != NULL){ n++; cur = cur->next; } return n;
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.